line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test::Reuse; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
Test::Reuse - Reusable Test::More tests in classes |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 DESCRIPTION |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
Test::Reuse was created for the sole purpose of writing really easy-to-use, reusable tests. You can create tests in a class, C |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 SYNOPSIS |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
OK, say we have the very same test running in several different tests. You don't want to just keep copy and pasting that code because it clutters up space when it doesn't need to. So we start by writing the test class to where our reusable tests will be imported from. |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
package MyTestClass; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
use Test::Reuse; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
subtest 'is_it_ok' => sub { |
20
|
|
|
|
|
|
|
my $test = shift; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
for (@_) { |
23
|
|
|
|
|
|
|
ok $_, "$_ seems just fine!"; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
}; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
The C method in class that uses C actually stores the tests that are reusable. It won't actually run a subtest. The first argument will always be the test class name. In this instance it is MyTestClass. |
28
|
|
|
|
|
|
|
Now let's write the actual test. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
#!perl |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
use MyTestClass; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
use_test 'is_it_ok', qw<1 2 3 4 0 5>; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
runtests(); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
That's it. We use C followed by the subtest name. You can supply optional arguments afterwards if you like. Remember to always call C when you're done, which is identical to C. |
39
|
|
|
|
|
|
|
In the above example it will loop through all of numbers in the array we provided and will obviously fail on the fifth argument (the 0). |
40
|
|
|
|
|
|
|
You can also run C within the test class to control the flow a bit more. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
package MyTestClass; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
use Test::Reuse; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
subtest 'is_it_ok' => sub { |
47
|
|
|
|
|
|
|
my $test = shift; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
if (@_) { |
50
|
|
|
|
|
|
|
for (@_) { |
51
|
|
|
|
|
|
|
ok $_, "$_ seems just fine!"; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
else { |
55
|
|
|
|
|
|
|
use_test 'show_problem', 'No arguments for is_it_ok'; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
}; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
subtest 'show_problem' => sub { |
60
|
|
|
|
|
|
|
my ($test, $text) = @_; |
61
|
|
|
|
|
|
|
note "Woops!: ${text}"; |
62
|
|
|
|
|
|
|
}; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=cut |
65
|
|
|
|
|
|
|
|
66
|
1
|
|
|
1
|
|
75860
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
37
|
|
67
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1162
|
|
68
|
1
|
|
|
1
|
|
11
|
use base 'Test::More'; |
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
273
|
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
$Test::Reuse::subtests = {}; |
71
|
|
|
|
|
|
|
$Test::Reuse::base = ""; |
72
|
|
|
|
|
|
|
$Test::Reuse::VERSION = '0.001'; |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub import { |
75
|
1
|
|
|
1
|
|
9
|
my $class = shift; |
76
|
1
|
|
|
|
|
3
|
my $caller = caller(1); |
77
|
1
|
|
|
|
|
2
|
$Test::Reuse::base = caller; |
78
|
1
|
50
|
|
|
|
24
|
distribute($caller) |
79
|
|
|
|
|
|
|
unless $Test::Reuse::base->can('ok'); |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub distribute { |
83
|
0
|
|
|
0
|
0
|
|
my $caller = shift; |
84
|
0
|
|
|
|
|
|
my $base = $Test::Reuse::base; |
85
|
|
|
|
|
|
|
{ |
86
|
1
|
|
|
1
|
|
15
|
no strict 'refs'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
470
|
|
|
0
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
|
for my $method (keys %{"Test::More::"}) { |
|
0
|
|
|
|
|
|
|
88
|
0
|
0
|
0
|
|
|
|
*{"${caller}::${method}"} = *{"Test::More::${method}"} |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
unless substr($method, 0, 1) eq '_' or $method eq uc($method); |
90
|
0
|
0
|
0
|
|
|
|
*{"${base}::${method}"} = *{"Test::More::${method}"} |
|
0
|
|
0
|
|
|
|
|
|
0
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
unless substr($method, 0, 1) eq '_' or $method eq uc($method) or $method eq 'subtest'; |
92
|
|
|
|
|
|
|
} |
93
|
0
|
|
|
|
|
|
*{"${caller}::use_test"} = \&use_test; |
|
0
|
|
|
|
|
|
|
94
|
0
|
|
|
|
|
|
*{"${caller}::runtests"} = *{"Test::More::done_testing"}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
*{"${base}::use_test"} = \&use_test; |
|
0
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
*{"${base}::subtest"} = \&subtest; |
|
0
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub subtest { |
101
|
0
|
|
|
0
|
1
|
|
my ($name, $code) = @_; |
102
|
0
|
|
|
|
|
|
$Test::Reuse::subtests->{$name} = $code; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub use_test { |
106
|
0
|
|
|
0
|
1
|
|
my $base = $Test::Reuse::base; |
107
|
0
|
|
|
|
|
|
my $test = shift; |
108
|
0
|
0
|
|
|
|
|
__PACKAGE__->note("Can't use test '$test'. It's not included by $base") |
109
|
|
|
|
|
|
|
if !$Test::Reuse::subtests->{$test}; |
110
|
0
|
0
|
|
|
|
|
$Test::Reuse::subtests->{$test}->($base, @_) if $Test::Reuse::subtests->{$test}; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=head1 METHODS |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
Test::Reuse uses all the methods from L, but there are a couple that are used just in this module. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=head2 use_test |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
Calls a test from the test class. They must be defined in the test class using C |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
use_test 'method_name', qw; |
122
|
|
|
|
|
|
|
use_test 'my_test'; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=head2 subtest |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Technically this works exactly the same as Test::More's subtest in your test file, but in the test class it simply defines a reusable test. |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
subtest 'reusable_test_name' => sub { |
129
|
|
|
|
|
|
|
my $test_class = shift; |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
note "Running from ${test_class}"; |
132
|
|
|
|
|
|
|
}; |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head2 runtests |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
I don't like the way C looks, so swapped it for C. But you are welcome to use either one in your code. This MUST be run at the bottom of your normal test file (.t), or it will freak out. Which is pretty normal if you don't declare a plan. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head1 LIMITATIONS |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
This module is still new, so there are plenty. The main one at the moment being that you can only C |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=head1 AUTHOR |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Brad Haywood |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head1 LICENSE |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
You may distribute this code under the same terms as Perl itself, because Perl is awesome, and so are you for using it. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=cut |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
1; |