The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Test::YAFT - Yet another testing framework

SYNOPSIS

        use Test::YAFT;

        it "should pass this test"
                => got    => scalar do { ... }
                => expect => $expected_value
                ;

DISCLAIMER

Please accept the fact that I'm not English native speaker so this documentation may contain improper grammar or wording making it harder to understand.

If you encounter such place, please visit project's issue tracking.

DESCRIPTION

This module combines features of multiple test libraries providing its own, BDD inspired, Context oriented, testing approach.

GLOSSARY

assert

Assert function performs actual value comparison.

expectation

Expectation function provides object (Test::Deep::Cmp) describing expected value.

plumbing

Similar concept to git, plumbing functions are used to build higher level asserts, expectations, and/or tools.

Test::YAFT AND OTHER LIBRARIES

Please read following documentation how are other test libraries mapped into Test::YAFT workflow.

Test::YAFT::Test::Deep
Test::YAFT::Test::Exception
Test::YAFT::Test::More
Test::YAFT::Test::Spec
Test::YAFT::Test::Warnings

This document contains reference manual. If you want some kind of tutorial, please visit Test::YAFT::Introduction as well.

EXPORTED SYMBOLS

This module exports symbols using Exporter::Tiny.

Asserts

        use Test::YAFT qw[ :asserts ];

Assert functions are exported by default.

Every assert accepts (if any) test message as a first (positional) parameter, with restof parameters using named approach.

When assert performs multiple expectations internally, it always reports as one, using provided test message, failing early.

Named parameters are provided either via key/value pairs

        ok "test title"
                => got => $value
                ;

or via builder functions

        ok "test title"
                => got { build got }
                ;

Coding style note: I suggest to use coding style as presented in all examples, with one parameter per line, leading with fat comma.

fail

        return fail 'what failed';
        return fail 'what failed'
                => diag => "diagnostic message"
                ;
        return fail 'what failed'
                => diag => sub { "diagnostic message" }
                ;

Likewise "fail" in Test::More it also always fails, but it also accepts additional parameter - diagnostic message to show.

When diagnostic message is a CODEREF, it is executed and its result is treated as list of diagnostic messages (passed to diag)

had_no_warnings

        had_no_warnings;
        had_no_warnings 'title';

Reexported from Test::Warnings

it

        it "should be ..."
                => got    => ...
                => expect => ...
                ;

Basic test primitive, used by all other test functions. It uses Test::Deep's cmp_deeply to compare values.

In addition to Test::Deep's stack also uses Test::Difference to report differences when failed.

When expected value is Test::Deep::Bool then it uses Test::More's ok.

Accepted named(-like) parameters:

arrange
        it "should ..."
                => arrange { foo => "bar" }
                => arrange { bar => "baz" }
                ;

arrange { } blocks are evaluated in context of it-local frame before resolving value under test (got { }).

arrange { } blocks are always evaluated, even when value under test is provided as an exact value.

diag

Custom diagnostic message, printed out in case of failure.

When specified no other diagnostic message is printed.

Can be string, arrayref of strings, or coderef returning strings.

Coderef gets two parameters - Test::Deep stack and value under test.

expect

Expected value.

When specified and got { } block is used, additional expectation that it didn't die is executed before any other comparison.

got

Value under test.

When got { } block is used, it is evaluated and its error status is checked before actual comparison.

throws

Expected error.

When specified and got { } block is used, additional expectation that it did die is executed before any other comparison.

When both expect and throws parameters are specified, throws takes precedence.

See also Test::YAFT::Test::Exception.

nok

        nok "shouldn't be ..."
                => got    => ...
                ;

Simple shortcut to expect value behaving like boolean false.

ok

        ok "should be ..."
                => got    => ...
                ;

Simple shortcut to expect value behaving like boolean true.

pass

        pass 'what passed';

Reexported from Test::More

there

        there "should be ..."
                => got    => ...
                => expect => ...
                ;

Alias for it, providing convenient word to form meaningful English sentence

Expectations

Every expectation returns Test::Deep::Cmp object.

expect_all

Reexported "all" in Test::Deep.

expect_any

Reexported "any" in Test::Deep.

expect_array

Reexported "array" in Test::Deep.

expect_array_each

Reexported "array_each" in Test::Deep.

expect_array_elements_only

Reexported "arrayelementsonly" in Test::Deep.

expect_array_length

Reexported "arraylength" in Test::Deep.

expect_array_length_only

Reexported "arraylengthonly" in Test::Deep.

expect_bag

Reexported "bag" in Test::Deep.

expect_blessed

Reexported "blessed" in Test::Deep.

expect_bool

Reexported "bool" in Test::Deep.

expect_code

Reexported "code" in Test::Deep.

expect_compare

        it "should not exceed maximum value"
                => got    => $got
                => expect => expect_compare ('<=', $max)
                ;

Similar to "cmp_ok" in Test::More but provided as an expectation instead so it can be combined with other Test::Deep-based expectations.

expect_complement_to

        it "should be a boring number"
                => got    => $got
                => expect => expect_complement_to (42)
                ;

Negative expectation.

Usually it's easier to use overloaded complement operators ! or ~.

expect_false

Boolean expectation.

expect_hash

Reexported "hash" in Test::Deep.

expect_hash_each

Reexported "hash_each" in Test::Deep.

expect_hash_keys

Reexported "hashkeys" in Test::Deep.

expect_hash_keys_only

Reexported "hashkeysonly" in Test::Deep.

expect_isa

Reexported "Isa" in Test::Deep. Instance or inheritance expectation.

expect_listmethods

Reexported "listmethods" in Test::Deep.

expect_methods

Reexported "methods" in Test::Deep.

expect_no_class

Reexported "noclass" in Test::Deep.

expect_none

Reexported "none" in Test::Deep.

expect_none_of

Reexported "noneof" in Test::Deep.

expect_num

Reexported "num" in Test::Deep.

expect_obj_isa

Reexported "obj_isa" in Test::Deep.

expect_re

Reexported "re" in Test::Deep.

expect_ref_type

Reexported "reftype" in Test::Deep.

expect_regexp_matches

Reexported "regexpmatches" in Test::Deep.

expect_regexp_only

Reexported "regexponly" in Test::Deep.

expect_regexpref

Reexported "regexpref" in Test::Deep.

expect_regexpref_only

Reexported "regexprefonly" in Test::Deep.

expect_scalarref

Reexported "scalarref" in Test::Deep.

expect_scalarrefonly

Reexported "scalarrefonly" in Test::Deep.

expect_set

Reexported "set" in Test::Deep.

expect_shallow

Reexported "shallow" in Test::Deep.

expect_str

Reexported "str" in Test::Deep.

expect_subbag

Reexported "subbagof" in Test::Deep.

expect_subbag_of

Reexported "subbagof" in Test::Deep.

expect_subhash

Reexported "subhashof" in Test::Deep.

expect_subhash_of

Reexported "subhashof" in Test::Deep.

expect_subset

Reexported "subsetof" in Test::Deep.

expect_subset_of

Reexported "subsetof" in Test::Deep.

expect_superbag

Reexported "superbagof" in Test::Deep.

expect_superbag_of

Reexported "superbagof" in Test::Deep.

expect_superhash

Reexported "superhashof" in Test::Deep.

expect_superhash_of

Reexported "superhashof" in Test::Deep.

expect_superset

Reexported "supersetof" in Test::Deep.

expect_superset_of

Reexported "supersetof" in Test::Deep.

expect_true

Boolean expectation.

expect_use_class

Reexported "useclass" in Test::Deep.

expect_value

        => expect => expect_value (42)

Wraps any value as an expectation.

ignore

Reexported "ignore" in Test::Deep.

Helper Functions

        use Test::YAFT qw[ :helpers ];

Helper functions are exported by default.

Functions helping to organize your tests.

BAIL_OUT

Reexported "BAIL_OUT" in Test::More

arrange

        arrange { foo => "bar" };

        it "should ..."
                => arrange { foo => "bar2" }
                => got { $foo->method (deduce 'foo') }
                => expect => ...
                ;

Arrange block is treated as a function providing arguments for Context::Singleton's proclaim.

Arrange block returns a guard object, which is evaluated in frame valid at the time of evaluation (timely evaluation is responsibility of it).

When arrange { } is called in void context, it is evaluated immediately.

Validity of values follows Context::Singleton rules, so for example

        # This is available globally
        arrange { foo => "global value" };

        subtest "subtest" => sub {
                # This is available in scope of subtest (it creates its own frame)
                arrange { foo => "subtest local" };

                # This is available only in scope of 'it' (ie, insite got { })
                it "should ..."
                        => got { ... }
                        => arrange { foo => "assert local" }
                        ;
        };

diag

Reexported "diag" in Test::More

done_testing

Reexported "done_testing" in Test::More

explain

Reexported "explain" in Test::More

got

Can be used to specify code to build test value or to test that given code should / shouldn't throw an exception.

        it "should die"
                => got { $foo->do_something }
                => throws => expect_obj_isa (...)
                ;

When used, it always checks error status first before checking provided expectations.

note

Reexported "note" in Test::More

plan

Reexported "plan" in Test::More

skip

Reexported "skip" in Test::More

subtest

        subtest "title" => sub {
                ...;
        }

Similar to "subtest" in Test::More but also creates new Context::Singleton frame for each subtest.

todo

Reexported "todo" in Test::More

todo_skip

Reexported "todo_skip" in Test::More

Plumbing Functions

        use Test::YAFT qw[ :plumbings ];

Functions helping writing your custom asserts, expectations, and/or tools. Plumbing functions are not exported by default.

cmp_details

        use Test::YAFT qw[ cmp_details ];
        my ($ok, $stack) = cmp_details ($a, $b);

Reexported "cmp_details" in Test::Deep.

deep_diag

        use Test::YAFT qw[ deep_diag ];
        deep_diag ($stack);

Reexported "deep_diag" in Test::Deep.

eq_deeply

        use Test::YAFT qw[ eq_deeply ];
        if (eq_deeply ($a, $b)) {
        }

Reexported "eq_deeply" in Test::Deep.

test_deep_cmp

Creates "anonymous" (as far as Perl supports) Test::Deep comparator class. Returns created class name.

Typical usage

        sub expect_foo {
                state $class = test_deep_cmp (
                        isa => ...,
                        descend => ...,
                        renderGot => ...,
                );

                $class->new (@_);
        }

Accepts named arguments

isa => <PACKAGE>

Parent class, default: Test::YAFT::Cmp.

<METHOD> => <CODEREF>

Every other named parameter is treated as a method name to install into created namespace.

test_frame (&)

        use Test::YAFT qw[ test_frame ];
        sub my_assert {
                test_frame {
                        ...
                };
        }

Utility function to populate required boring details like

adjusting "level" in Test::Builder
create "frame" in Context::Singleton

AUTHOR

Branislav Zahradník <barney@cpan.org>

COPYRIGHT AND LICENCE

Test::YAFT distribution is distributed under Artistic Licence 2.0.