1Test::Roo(3) User Contributed Perl Documentation Test::Roo(3)
2
3
4
6 Test::Roo - Composable, reusable tests with roles and Moo
7
9 version 1.004
10
12 Define test behaviors and required fixtures in a role:
13
14 # t/lib/ObjectCreation.pm
15
16 package ObjectCreation;
17 use Test::Roo::Role; # loads Moo::Role and Test::More
18
19 requires 'class'; # we need this fixture
20
21 test 'object creation' => sub {
22 my $self = shift;
23 require_ok( $self->class );
24 my $obj = new_ok( $self->class );
25 };
26
27 1;
28
29 Provide fixtures and run tests from the .t file:
30
31 # t/test.t
32
33 use Test::Roo; # loads Moo and Test::More
34 use lib 't/lib';
35
36 # provide the fixture
37 has class => (
38 is => 'ro',
39 default => sub { "Digest::MD5" },
40 );
41
42 # specify behaviors to test
43 with 'ObjectCreation';
44
45 # give our subtests a pretty label
46 sub _build_description { "Testing " . shift->class }
47
48 # run the test with default fixture
49 run_me;
50
51 # run the test with different fixture
52 run_me( { class => "Digest::SHA1" } );
53
54 done_testing;
55
56 Result:
57
58 $ prove -lv t
59 t/test.t ..
60 ok 1 - require Digest::MD5;
61 ok 2 - The object isa Digest::MD5
62 1..2
63 ok 1 - object creation
64 1..1
65 ok 1 - Testing Digest::MD5
66 ok 1 - require Digest::SHA1;
67 ok 2 - The object isa Digest::SHA1
68 1..2
69 ok 1 - object creation
70 1..1
71 ok 2 - Testing Digest::SHA1
72 1..2
73 ok
74 All tests successful.
75 Files=1, Tests=2, 0 wallclock secs ( 0.02 usr 0.01 sys + 0.06 cusr 0.00 csys = 0.09 CPU)
76 Result: PASS
77
79 This module allows you to compose Test::More tests from roles. It is
80 inspired by the excellent Test::Routine module, but uses Moo instead of
81 Moose. This gives most of the benefits without the need for Moose as a
82 test dependency.
83
84 Test files are Moo classes. You can define any needed test fixtures as
85 Moo attributes. You define tests as method modifiers -- similar in
86 concept to "subtest" in Test::More, but your test method will be passed
87 the test object for access to fixture attributes. You may compose any
88 Moo::Role into your test to define attributes, require particular
89 methods, or define tests.
90
91 This means that you can isolate test behaviors into roles which require
92 certain test fixtures in order to run. Your main test file will
93 provide the fixtures and compose the roles to run. This makes it easy
94 to reuse test behaviors.
95
96 For example, if you are creating tests for Awesome::Module, you could
97 create the test behaviors as Awesome::Module::Test::Role and distribute
98 it with your module. If another distribution subclasses
99 Awesome::Module, it can compose the Awesome::Module::Test::Role
100 behavior for its own tests.
101
102 No more copying and pasting tests from a super class! Superclasses
103 define and share their tests. Subclasses provide their own fixtures
104 and run the tests.
105
107 Importing Test::Roo also loads Moo (which gives you strictures with
108 fatal warnings and other goodies) and makes the current package a
109 subclass of Test::Roo::Class.
110
111 Importing also loads Test::More. No test plan is used. The
112 "done_testing" function must be used at the end of every test file.
113 Any import arguments are passed through to Test::More's "import"
114 method.
115
116 See also Test::Roo::Role for test role usage.
117
118 Creating fixtures
119 You can create fixtures with normal Moo syntax. You can even make them
120 lazy if you want:
121
122 has fixture => (
123 is => 'lazy'
124 );
125
126 sub _build_fixture { ... }
127
128 This becomes really useful with Test::Roo::Role. A role could define
129 the attribute and require the builder method to be provided by the main
130 test class.
131
132 Composing test roles
133 You can use roles to define units of test behavior and then compose
134 them into your test class using the "with" function. Test roles may
135 define attributes, declare tests, require certain methods and anything
136 else you can regularly do with roles.
137
138 use Test::Roo;
139
140 with 'MyTestRole1', 'MyTestRole2';
141
142 See Test::Roo::Role and the Test::Roo::Cookbook for details and
143 examples.
144
145 Setup and teardown
146 You can add method modifiers around the "setup" and "teardown" methods
147 and these will be run before tests begin and after tests finish
148 (respectively).
149
150 before setup => sub { ... };
151
152 after teardown => sub { ... };
153
154 You can also add method modifiers around "each_test", which will be run
155 before and after every individual test. You could use these to prepare
156 or reset a fixture.
157
158 has fixture => ( is => 'lazy, clearer => 1, predicate => 1 );
159
160 after each_test => sub { shift->clear_fixture };
161
162 Roles may also modify "setup", "teardown", and "each_test", so the
163 order that modifiers will be called will depend on when roles are
164 composed. Be careful with "each_test", though, because the global
165 effect may make composition more fragile.
166
167 You can call test functions in modifiers. For example, you could
168 confirm that something has been set up or cleaned up.
169
170 before each_test => sub { ok( ! shift->has_fixture ) };
171
172 Running tests
173 The simplest way to use Test::Roo with a single .t file is to let the
174 "main" package be the test class and call "run_me" in it:
175
176 # t/test.t
177 use Test::Roo; # loads Moo and Test::More
178
179 has class => (
180 is => 'ro',
181 default => sub { "Digest::MD5" },
182 );
183
184 test 'load class' => sub {
185 my $self = shift;
186 require_ok( $self->class );
187 }
188
189 run_me;
190 done_testing;
191
192 Calling "run_me(@args)" is equivalent to calling
193 "__PACKAGE__->run_tests(@args)" and runs tests for the current package.
194
195 You may specify an optional description or hash reference of
196 constructor arguments to customize the test object:
197
198 run_me( "load MD5" );
199 run_me( { class => "Digest::MD5" } );
200 run_me( "load MD5", { class => "Digest::MD5" } );
201
202 See Test::Roo::Class for more about the "run_tests" method.
203
204 Alternatively, you can create a separate package (in the test file or
205 in a separate .pm file) and run tests explicitly on that class.
206
207 # t/test.t
208 package MyTest;
209 use Test::Roo;
210
211 use lib 't/lib';
212
213 has class => (
214 is => 'ro',
215 required => 1,
216 );
217
218 with 'MyTestRole';
219
220 package main;
221 use strictures;
222 use Test::More;
223
224 for my $c ( qw/Digest::MD5 Digest::SHA/ ) {
225 MyTest->run_tests("Testing $c", { class => $c } );
226 }
227
228 done_testing;
229
231 Loading Test::Roo exports subroutines into the calling package to
232 declare and run tests.
233
234 test
235 test $label => sub { ... };
236
237 The "test" function adds a subtest. The code reference will be called
238 with the test object as its only argument.
239
240 Tests are run in the order declared, so the order of tests from roles
241 will depend on when they are composed relative to other test
242 declarations.
243
244 top_test
245 top_test $label => sub { ... };
246
247 The "top_test" function adds a "top level" test. Works exactly like
248 "test" except it will not start a subtest. This is especially useful
249 in very simple testing situations where the extra subtest level is just
250 noise.
251
252 So for example the following test
253
254 # t/test.t
255 use Test::Roo;
256
257 has class => (
258 is => 'ro',
259 required => 1,
260 );
261
262 top_test basic => sub {
263 my $self = shift;
264
265 require_ok($self->class);
266 isa_ok($self->class->new, $self->class);
267 };
268
269 for my $c ( qw/Digest::MD5 Digest::SHA/ ) {
270 run_me("Testing $c", { class => $c } );
271 }
272
273 done_testing;
274
275 produces the following TAP
276
277 t/test.t ..
278 ok 1 - require Digest::MD5;
279 ok 2 - The object isa Digest::MD5
280 1..2
281 ok 1 - Testing Digest::MD5
282 ok 1 - require Digest::SHA1;
283 ok 2 - The object isa Digest::SHA1
284 1..2
285 ok 2 - Testing Digest::SHA1
286 1..2
287 ok
288 All tests successful.
289 Files=1, Tests=2, 0 wallclock secs ( 0.02 usr 0.01 sys + 0.06 cusr 0.00 csys = 0.09 CPU)
290 Result: PASS
291
292 run_me
293 run_me;
294 run_me( $description );
295 run_me( $init_args );
296 run_me( $description, $init_args );
297
298 The "run_me" function calls the "run_tests" method on the current
299 package and passes all arguments to that method. It takes a
300 description and/or a hash reference of constructor arguments.
301
303 While this module was inspired by Test::Routine, it is not a drop-in
304 replacement. Here is an overview of major differences:
305
306 · Test::Roo uses Moo; Test::Routine uses Moose
307
308 · Loading Test::Roo makes the importing package a class; in
309 Test::Routine it becomes a role
310
311 · Loading Test::Roo loads Test::More; Test::Routine does not
312
313 · In Test::Roo, "run_test" is a method; in Test::Routine it is a
314 function and takes arguments in a different order
315
316 · In Test::Roo, all role composition must be explicit using "with";
317 in Test::Routine, the "run_tests" command can also compose roles
318
319 · In Test::Roo, test blocks become method modifiers hooked on an
320 empty method; in Test::Routine, they become methods run via
321 introspection
322
323 · In Test::Roo, setup and teardown are done by modifying "setup" and
324 "teardown" methods; in Test::Routine they are done by modifying
325 "run_test"
326
328 Bugs / Feature Requests
329 Please report any bugs or feature requests through the issue tracker at
330 <https://github.com/dagolden/Test-Roo/issues>. You will be notified
331 automatically of any progress on your issue.
332
333 Source Code
334 This is open source software. The code repository is available for
335 public review and contribution under the terms of the license.
336
337 <https://github.com/dagolden/Test-Roo>
338
339 git clone https://github.com/dagolden/Test-Roo.git
340
342 David Golden <dagolden@cpan.org>
343
345 · Arthur Axel 'fREW' Schmidt <frioux@gmail.com>
346
347 · Diab Jerius <djerius@gmail.com>
348
350 This software is Copyright (c) 2013 by David Golden.
351
352 This is free software, licensed under:
353
354 The Apache License, Version 2.0, January 2004
355
356
357
358perl v5.32.0 2020-07-28 Test::Roo(3)