=for comment Documentation generated by YARD v0.6.1 and yard-pod-plugin v0.1. =head1 NAME Test::Mini::Unit - Declarative Sugar for Test::Mini =head1 DESCRIPTION Test::Mini::Unit aims to provide a simpler, boilerplate-free environment for writing new L<<<< S<<<<< Test::Mini >>>>>|Test::Mini >>>> test cases. While Test::Mini itself is a fairly reasonable environment with very little overhead verbosity, the overhead of creating a new class -- or set of classes -- in Perl can still be a bit more distracting than you'd really like. =head2 Enter Test::Mini::Unit At first glance, Test::Mini::Unit provides moderate improvements over the traditional style, transforming this: package t::Test use base 'Test::Mini::TestCase'; use strict; use warnings; use Test::Mini::Assertions; sub setup { # do something } sub test_some_code { assert($something_true); } sub teardown { # undo something } 1; Into this: use Test::Mini::Unit; case t::Test { setup { # do something } test some_code { assert($something_true); } teardown { # undo something } } =head2 Advice But Test::Mini::Unit really begins to shine as your test cases take on more complexity. Multiple calls to the test advice methods (C<<<< setup >>>> and C<<<< teardown >>>>) will stack like C<<<< BEGIN >>>> and C<<<< END >>>> blocks, allowing you to co-locate tests and relevant advice. # Traditional sub setup { # do a bunch of setup for test_one # ... # do a bunch of setup for test_two # ... } sub test_one { ... } sub test_two { ... } # Test::Mini::Unit setup { "do setup for test_one" } sub test_one { ... } setup { "do setup for test_two" } sub test_two { ... } =head2 Test-Local Storage Per-test local storage is automatically available as C<<<< $self >>>> from all advice and test blocks. setup { $self->{data} = Package->new() } test data { assert_isa($self->{data}, 'Package') } teardown { unlink $self->{tmpfile} } =head2 Nesting And perhaps most usefully, test cases can be B<<<< nested >>>>. Nested test cases inherit all their outer scope's test advice, allowing you to build richer tests with far less code. case t::IO::Scalar { setup { $self->{buffer} = IO::Scalar->new() } test can_read { assert_can($self->{buffer}, 'read') } test can_write { assert_can($self->{buffer}, 'write') } test is_empty { assert_empty("@{[$self->{buffer}]}") } case AfterWritingString { setup { $self->{buffer}->print('String!') } test contents { assert_equal("@{[$self->{buffer}]}", 'String!'); } } case AfterWritingObject { setup { $self->{buffer}->print($self) } test contents { assert_equal("@{[$self->{buffer}]}", "$self"); } } } =head2 Sharing Tests... In some cases, you may find it useful to reuse the same tests in different cases. For this purpose, the C<<<< shared >>>> and C<<<< reuse >>>> keywords exist: shared BasicBookTests { test has_pages { ... } test pages_have_text { ... } } case Book { reuse BasicBookTests; } case LargePrintBook { reuse BasicBookTests; test words_should_be_big { ... } } =head2 ... And Reusing Them Groups of shared tests may also be nested inside C<<<< case >>>> blocks, where they will inherit the namespace of their parent. Since shared tests will most commonly see reuse inside either the C<<<< case >>>> they're declared in or a nested case, it's not usually necessary to specify the full package name. The C<<<< reuse >>>> keyword will try, therefore, to infer the fully qualified package name from the name it's given. (You can always specify the full name yourself by prepending '::'.) shared CommonTests { # __PACKAGE__ is 'Nested::CommonTests' } case Nested { shared CommonTests { # __PACKAGE__ is 'Nested::CommonTests' } case Deeply { shared CommonTests { # __PACKAGE__ is 'Nested::Deeply::CommonTests' } # includes Nested::Deeply::CommonTests reuse CommonTests; # includes Nested::CommonTests reuse Nested::CommonTests; # includes CommonTests reuse ::CommonTests; } # includes Nested::CommonTests reuse CommonTests; } =head2 Automatic 'use' To automatically use packages inside all your test cases (for example, your own custom assertions), simply pass the 'with' option to Test::Mini::Unit; it can accept either a single package name or an array. use Test::Mini::Unit (with => [ My::Assertions, My::HelperFuncs ]); case t::TestCase { # My::Assertions and My::HelperFuncs are already imported here. case Nested { # In here, too. } shared CommonTests { # Yup, here too. } } See Also: =over =item * L<<<< S<<<<< Test::Mini >>>>>|Test::Mini >>>> =back =head1 AUTHOR Pieter van de Bruggen