NAME
Test::Roo - Composable tests with roles and Moo
VERSION
version 0.002
SYNOPSIS
A test file:
# t/test.t
use Test::Roo; # loads Moo and Test::More
use lib 't/lib';
has class => (
is => 'ro',
default => sub { "Digest::MD5" },
);
run_tests(qw/MyTestRole/);
A testing role:
# t/lib/MyTestRole.pm
package MyTestRole;
use Test::Roo::Role; # loads Moo::Role and Test::More
requires 'class';
test 'object creation' => sub {
my $self = shift;
require_ok( $self->class );
my $obj = new_ok( $self->class );
};
1;
DESCRIPTION
This module allows you to compose Test::More tests from roles. It is
inspired by the excellent Test::Routine module, but uses Moo instead of
Moose. This gives most of the benefits without the need for Moose as a
test dependency.
Test files are Moo classes. You can define any needed test fixtures as
Moo attributes. You define tests as method modifiers -- similar in
concept to "subtest" in Test::More, but your test method will be passed
the test object for access to fixture attributes. You may compose any
Moo::Role into your test to define attributes, require particular
methods, or define tests.
This means that you can isolate test *behaviors* into roles which
require certain test *fixtures* in order to run. Your main test file
will provide the fixtures and compose the roles to run. This makes it
easy to reuse test behaviors.
For example, if you are creating tests for Awesome::Module, you could
create the test behaviors as Awesome::Module::Test::Role and distribute
it with your module. If another distribution subclasses Awesome::Module,
it can compose the Awesome::Module::Test::Role behavior for its own
tests.
No more copying and pasting tests from a super class! Superclasses
define and share their tests. Subclasses provide their own fixtures and
run the tests.
USAGE
Importing Test::Roo also loads Moo (which gives you strictures with
fatal warnings and other goodies) and Test::More. No test plan is used.
The "done_testing" function will be called for you automatically.
See also Test::Roo::Role for test role usage.
If you have to call "plan skip_all", do it in the main body of your
code, not in a test or modifier.
Creating fixtures
You can create fixtures with normal Moo syntax. You can even make them
lazy if you want:
has fixture => (
is => 'lazy'
);
sub _build_fixture { ... }
This becomes really useful with Test::Roo::Role. A role could define the
attribute and require the builder method to be provided by the main test
class.
Setup and teardown
You can add method modifiers around the "setup" and "teardown" methods
and these will be run before and after all tests (respectively).
before setup => sub { ... };
after teardown => sub { ... };
Roles may also modify these, so the order that modifiers will be called
will depend on when roles are composed.
You can even call test functions in these, for example, to confirm that
something has been set up or cleaned up.
Running tests
The simplest way to use Test::Roo is to make the "main" package in your
test file the test class and call "run_tests" in it:
# t/test.t
use Test::Roo; # loads Moo and Test::More
use lib 't/lib';
has class => (
is => 'ro',
default => sub { "Digest::MD5" },
);
run_tests(qw/MyTestRole/);
If you do this, however, you can't specify arguments to the test class
constructor and can only run the test class once.
Alternatively, you can create a separate package (in the test file or in
a separate ".pm" file) and create and run the test objects yourself:
# t/test.t
package MyTest;
use Test::Roo;
use lib 't/lib';
has class => (
is => 'ro',
required => 1,
);
with 'MyTestRole';
package main;
use strictures;
use Test::More;
for my $c ( qw/Digest::MD5 Digest::SHA/ ) {
my $obj = new_ok( 'MyTest', [class => $c] );
$obj->run_me;
}
done_testing;
Note that, in this case, you will need to compose your own roles with
"with" and call "done_testing" yourself.
FUNCTIONS
test
test $label => sub { ... };
The "test" function adds a subtest. The code reference will be called
with the test object as its only argument.
Tests are run in the order declared, so the order of tests from roles
will depend on when they are composed relative to other test
declarations.
run_tests
run_tests( @optional_roles );
The "run_tests" function composes an optional list of roles into the
calling package, creates an object without arguments, calls the "run_me"
method on it, and calls "done_testing".
Because this is usually at the end of the test file, all attributes,
tests and method modifiers in the main test file will be set up before
roles are composed. If this isn't what you want, use "with" earlier in
the file and omit the role from the arguments to "run_tests".
Because it calls "done_testing", it may only be called once for a given
test class.
IMPORTED METHODS
Loading Test::Roo imports several subroutines into the calling package
to create required default methods.
run_me
$obj->run_me;
This method runs the setup method (triggering modifiers), runs the
tests, and calls the teardown method (triggering modifiers). It is
called by the "run_tests" function, or you can call it yourself after
composing roles with "with".
setup, teardown, my_tests
These are used to anchor method modifiers in the testing class and
should not be otherwise modified or called directly.
SUPPORT
Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker at
<https://github.com/dagolden/test-roo/issues>. You will be notified
automatically of any progress on your issue.
Source Code
This is open source software. The code repository is available for
public review and contribution under the terms of the license.
<https://github.com/dagolden/test-roo>
git clone git://github.com/dagolden/test-roo.git
AUTHOR
David Golden <dagolden@cpan.org>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2013 by David Golden.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004