2
Test::Roo - Composable, reusable tests with roles and Moo
8
Define test behaviors and required fixtures in a role:
10
# t/lib/ObjectCreation.pm
12
package ObjectCreation;
13
use Test::Roo::Role; # loads Moo::Role and Test::More
15
requires 'class'; # we need this fixture
17
test 'object creation' => sub {
19
require_ok( $self->class );
20
my $obj = new_ok( $self->class );
25
Provide fixtures and run tests from the .t file:
29
use Test::Roo; # loads Moo and Test::More
35
default => sub { "Digest::MD5" },
38
# specify behaviors to test
39
with 'ObjectCreation';
41
# give our subtests a pretty label
42
sub _build_description { "Testing " . shift->class }
44
# run the test with default fixture
47
# run the test with different fixture
48
run_me( { class => "Digest::SHA1" } );
56
ok 1 - require Digest::MD5;
57
ok 2 - The object isa Digest::MD5
59
ok 1 - object creation
61
ok 1 - Testing Digest::MD5
62
ok 1 - require Digest::SHA1;
63
ok 2 - The object isa Digest::SHA1
65
ok 1 - object creation
67
ok 2 - Testing Digest::SHA1
71
Files=1, Tests=2, 0 wallclock secs ( 0.02 usr 0.01 sys + 0.06 cusr 0.00 csys = 0.09 CPU)
75
This module allows you to compose Test::More tests from roles. It is
76
inspired by the excellent Test::Routine module, but uses Moo instead of
77
Moose. This gives most of the benefits without the need for Moose as a
80
Test files are Moo classes. You can define any needed test fixtures as
81
Moo attributes. You define tests as method modifiers -- similar in
82
concept to "subtest" in Test::More, but your test method will be passed
83
the test object for access to fixture attributes. You may compose any
84
Moo::Role into your test to define attributes, require particular
85
methods, or define tests.
87
This means that you can isolate test *behaviors* into roles which
88
require certain test *fixtures* in order to run. Your main test file
89
will provide the fixtures and compose the roles to run. This makes it
90
easy to reuse test behaviors.
92
For example, if you are creating tests for Awesome::Module, you could
93
create the test behaviors as Awesome::Module::Test::Role and distribute
94
it with your module. If another distribution subclasses Awesome::Module,
95
it can compose the Awesome::Module::Test::Role behavior for its own
98
No more copying and pasting tests from a super class! Superclasses
99
define and share their tests. Subclasses provide their own fixtures and
103
Importing Test::Roo also loads Moo (which gives you strictures with
104
fatal warnings and other goodies) and makes the current package a
105
subclass of Test::Roo::Class.
107
Importing also loads Test::More. No test plan is used. The
108
"done_testing" function must be used at the end of every test file. Any
109
import arguments are passed through to Test::More's "import" method.
111
See also Test::Roo::Role for test role usage.
114
You can create fixtures with normal Moo syntax. You can even make them
121
sub _build_fixture { ... }
123
This becomes really useful with Test::Roo::Role. A role could define the
124
attribute and require the builder method to be provided by the main test
128
You can use roles to define units of test behavior and then compose them
129
into your test class using the "with" function. Test roles may define
130
attributes, declare tests, require certain methods and anything else you
131
can regularly do with roles.
135
with 'MyTestRole1', 'MyTestRole2';
137
See Test::Roo::Role and the Test::Roo::Cookbook for details and
141
You can add method modifiers around the "setup" and "teardown" methods
142
and these will be run before tests begin and after tests finish
145
before setup => sub { ... };
147
after teardown => sub { ... };
149
You can also add method modifiers around "each_test", which will be run
150
before and after every individual test. You could use these to prepare
153
has fixture => ( is => 'lazy, clearer => 1, predicate => 1 );
155
after each_test => sub { shift->clear_fixture };
157
Roles may also modify "setup", "teardown", and "each_test", so the order
158
that modifiers will be called will depend on when roles are composed. Be
159
careful with "each_test", though, because the global effect may make
160
composition more fragile.
162
You can call test functions in modifiers. For example, you could confirm
163
that something has been set up or cleaned up.
165
before each_test => sub { ok( ! shift->has_fixture ) };
168
The simplest way to use Test::Roo with a single .t file is to let the
169
"main" package be the test class and call "run_me" in it:
172
use Test::Roo; # loads Moo and Test::More
176
default => sub { "Digest::MD5" },
179
test 'load class' => sub {
181
require_ok( $self->class );
187
Calling "run_me(@args)" is equivalent to calling
188
"__PACKAGE__->run_tests(@args)" and runs tests for the current package.
190
You may specify an optional description or hash reference of constructor
191
arguments to customize the test object:
193
run_me( "load MD5" );
194
run_me( { class => "Digest::MD5" } );
195
run_me( "load MD5", { class => "Digest::MD5" } );
197
See Test::Roo::Class for more about the "run_tests" method.
199
Alternatively, you can create a separate package (in the test file or in
200
a separate .pm file) and run tests explicitly on that class.
219
for my $c ( qw/Digest::MD5 Digest::SHA/ ) {
220
MyTest->run_tests("Testing $c", { class => $c } );
226
Loading Test::Roo exports subroutines into the calling package to
227
declare and run tests.
230
test $label => sub { ... };
232
The "test" function adds a subtest. The code reference will be called
233
with the test object as its only argument.
235
Tests are run in the order declared, so the order of tests from roles
236
will depend on when they are composed relative to other test
241
run_me( $description );
242
run_me( $init_args );
243
run_me( $description, $init_args );
245
The "run_me" function calls the "run_tests" method on the current
246
package and passes all arguments to that method. It takes a description
247
and/or a hash reference of constructor arguments.
249
DIFFERENCES FROM TEST::ROUTINE
250
While this module was inspired by Test::Routine, it is not a drop-in
251
replacement. Here is an overview of major differences:
253
* Test::Roo uses Moo; Test::Routine uses Moose
255
* Loading Test::Roo makes the importing package a class; in
256
Test::Routine it becomes a role
258
* Loading Test::Roo loads Test::More; Test::Routine does not
260
* In Test::Roo, "run_test" is a method; in Test::Routine it is a
261
function and takes arguments in a different order
263
* In Test::Roo, all role composition must be explicit using "with"; in
264
Test::Routine, the "run_tests" command can also compose roles
266
* In Test::Roo, test blocks become method modifiers hooked on an empty
267
method; in Test::Routine, they become methods run via introspection
269
* In Test::Roo, setup and teardown are done by modifying "setup" and
270
"teardown" methods; in Test::Routine they are done by modifying
274
Bugs / Feature Requests
275
Please report any bugs or feature requests through the issue tracker at
276
<https://github.com/dagolden/Test-Roo/issues>. You will be notified
277
automatically of any progress on your issue.
280
This is open source software. The code repository is available for
281
public review and contribution under the terms of the license.
283
<https://github.com/dagolden/Test-Roo>
285
git clone https://github.com/dagolden/Test-Roo.git
288
David Golden <dagolden@cpan.org>
291
Diab Jerius <djerius@gmail.com>
293
COPYRIGHT AND LICENSE
294
This software is Copyright (c) 2013 by David Golden.
296
This is free software, licensed under:
298
The Apache License, Version 2.0, January 2004