1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
|
.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "Test::Tester 3pm"
.TH Test::Tester 3pm 2023-11-28 "perl v5.38.2" "Perl Programmers Reference Guide"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
Test::Tester \- Ease testing test modules built with Test::Builder
.SH SYNOPSIS
.IX Header "SYNOPSIS"
.Vb 1
\& use Test::Tester tests => 6;
\&
\& use Test::MyStyle;
\&
\& check_test(
\& sub {
\& is_mystyle_eq("this", "that", "not eq");
\& },
\& {
\& ok => 0, # expect this to fail
\& name => "not eq",
\& diag => "Expected: \*(Aqthis\*(Aq\enGot: \*(Aqthat\*(Aq",
\& }
\& );
.Ve
.PP
or
.PP
.Vb 1
\& use Test::Tester tests => 6;
\&
\& use Test::MyStyle;
\&
\& check_test(
\& sub {
\& is_mystyle_qr("this", "that", "not matching");
\& },
\& {
\& ok => 0, # expect this to fail
\& name => "not matching",
\& diag => qr/Expected: \*(Aqthis\*(Aq\es+Got: \*(Aqthat\*(Aq/,
\& }
\& );
.Ve
.PP
or
.PP
.Vb 1
\& use Test::Tester;
\&
\& use Test::More tests => 3;
\& use Test::MyStyle;
\&
\& my ($premature, @results) = run_tests(
\& sub {
\& is_database_alive("dbname");
\& }
\& );
\&
\& # now use Test::More::like to check the diagnostic output
\&
\& like($results[0]\->{diag}, "/^Database ping took \e\ed+ seconds$"/, "diag");
.Ve
.SH DESCRIPTION
.IX Header "DESCRIPTION"
If you have written a test module based on Test::Builder then Test::Tester
allows you to test it with the minimum of effort.
.SH "HOW TO USE (THE EASY WAY)"
.IX Header "HOW TO USE (THE EASY WAY)"
From version 0.08 Test::Tester no longer requires you to included anything
special in your test modules. All you need to do is
.PP
.Vb 1
\& use Test::Tester;
.Ve
.PP
in your test script \fBbefore\fR any other Test::Builder based modules and away
you go.
.PP
Other modules based on Test::Builder can be used to help with the
testing. In fact you can even use functions from your module to test
other functions from the same module (while this is possible it is
probably not a good idea, if your module has bugs, then
using it to test itself may give the wrong answers).
.PP
The easiest way to test is to do something like
.PP
.Vb 8
\& check_test(
\& sub { is_mystyle_eq("this", "that", "not eq") },
\& {
\& ok => 0, # we expect the test to fail
\& name => "not eq",
\& diag => "Expected: \*(Aqthis\*(Aq\enGot: \*(Aqthat\*(Aq",
\& }
\& );
.Ve
.PP
this will execute the is_mystyle_eq test, capturing its results and
checking that they are what was expected.
.PP
You may need to examine the test results in a more flexible way, for
example, the diagnostic output may be quite long or complex or it may involve
something that you cannot predict in advance like a timestamp. In this case
you can get direct access to the test results:
.PP
.Vb 5
\& my ($premature, @results) = run_tests(
\& sub {
\& is_database_alive("dbname");
\& }
\& );
\&
\& like($result[0]\->{diag}, "/^Database ping took \e\ed+ seconds$"/, "diag");
.Ve
.PP
or
.PP
.Vb 8
\& check_test(
\& sub { is_mystyle_qr("this", "that", "not matching") },
\& {
\& ok => 0, # we expect the test to fail
\& name => "not matching",
\& diag => qr/Expected: \*(Aqthis\*(Aq\es+Got: \*(Aqthat\*(Aq/,
\& }
\& );
.Ve
.PP
We cannot predict how long the database ping will take so we use
Test::More's \fBlike()\fR test to check that the diagnostic string is of the right
form.
.SH "HOW TO USE (THE HARD WAY)"
.IX Header "HOW TO USE (THE HARD WAY)"
\&\fIThis is here for backwards compatibility only\fR
.PP
Make your module use the Test::Tester::Capture object instead of the
Test::Builder one. How to do this depends on your module but assuming that
your module holds the Test::Builder object in \f(CW$Test\fR and that all your test
routines access it through \f(CW$Test\fR then providing a function something like this
.PP
.Vb 4
\& sub set_builder
\& {
\& $Test = shift;
\& }
.Ve
.PP
should allow your test scripts to do
.PP
.Vb 1
\& Test::YourModule::set_builder(Test::Tester\->capture);
.Ve
.PP
and after that any tests inside your module will captured.
.SH "TEST RESULTS"
.IX Header "TEST RESULTS"
The result of each test is captured in a hash. These hashes are the same as
the hashes returned by Test::Builder\->details but with a couple of extra
fields.
.PP
These fields are documented in Test::Builder in the \fBdetails()\fR function
.IP ok 2
.IX Item "ok"
Did the test pass?
.IP actual_ok 2
.IX Item "actual_ok"
Did the test really pass? That is, did the pass come from
Test::Builder\->\fBok()\fR or did it pass because it was a TODO test?
.IP name 2
.IX Item "name"
The name supplied for the test.
.IP type 2
.IX Item "type"
What kind of test? Possibilities include, skip, todo etc. See
Test::Builder for more details.
.IP reason 2
.IX Item "reason"
The reason for the skip, todo etc. See Test::Builder for more details.
.PP
These fields are exclusive to Test::Tester.
.IP diag 2
.IX Item "diag"
Any diagnostics that were output for the test. This only includes
diagnostics output \fBafter\fR the test result is declared.
.Sp
Note that Test::Builder ensures that any diagnostics end in a \en and
it in earlier versions of Test::Tester it was essential that you have
the final \en in your expected diagnostics. From version 0.10 onward,
Test::Tester will add the \en if you forgot it. It will not add a \en if
you are expecting no diagnostics. See below for help tracking down
hard to find space and tab related problems.
.IP depth 2
.IX Item "depth"
This allows you to check that your test module is setting the correct value
for \f(CW$Test::Builder::Level\fR and thus giving the correct file and line number
when a test fails. It is calculated by looking at \fBcaller()\fR and
\&\f(CW$Test::Builder::Level\fR. It should count how many subroutines there are before
jumping into the function you are testing. So for example in
.Sp
.Vb 1
\& run_tests( sub { my_test_function("a", "b") } );
.Ve
.Sp
the depth should be 1 and in
.Sp
.Vb 1
\& sub deeper { my_test_function("a", "b") }
\&
\& run_tests(sub { deeper() });
.Ve
.Sp
depth should be 2, that is 1 for the sub {} and one for \fBdeeper()\fR. This
might seem a little complex but if your tests look like the simple
examples in this doc then you don't need to worry as the depth will
always be 1 and that's what Test::Tester expects by default.
.Sp
\&\fBNote\fR: if you do not specify a value for depth in \fBcheck_test()\fR then it
automatically compares it against 1, if you really want to skip the depth
test then pass in undef.
.Sp
\&\fBNote\fR: depth will not be correctly calculated for tests that run from a
signal handler or an END block or anywhere else that hides the call stack.
.PP
Some of Test::Tester's functions return arrays of these hashes, just
like Test::Builder\->details. That is, the hash for the first test will
be array element 1 (not 0). Element 0 will not be a hash it will be a
string which contains any diagnostic output that came before the first
test. This should usually be empty, if it's not, it means something
output diagnostics before any test results showed up.
.SH "SPACES AND TABS"
.IX Header "SPACES AND TABS"
Appearances can be deceptive, especially when it comes to emptiness. If you
are scratching your head trying to work out why Test::Tester is saying that
your diagnostics are wrong when they look perfectly right then the answer is
probably whitespace. From version 0.10 on, Test::Tester surrounds the
expected and got diag values with single quotes to make it easier to spot
trailing whitespace. So in this example
.PP
.Vb 4
\& # Got diag (5 bytes):
\& # \*(Aqabcd \*(Aq
\& # Expected diag (4 bytes):
\& # \*(Aqabcd\*(Aq
.Ve
.PP
it is quite clear that there is a space at the end of the first string.
Another way to solve this problem is to use colour and inverse video on an
ANSI terminal, see below COLOUR below if you want this.
.PP
Unfortunately this is sometimes not enough, neither colour nor quotes will
help you with problems involving tabs, other non-printing characters and
certain kinds of problems inherent in Unicode. To deal with this, you can
switch Test::Tester into a mode whereby all "tricky" characters are shown as
\&\e{xx}. Tricky characters are those with ASCII code less than 33 or higher
than 126. This makes the output more difficult to read but much easier to
find subtle differences between strings. To turn on this mode either call
\&\f(CWshow_space()\fR in your test script or set the \f(CW\*(C`TESTTESTERSPACE\*(C'\fR environment
variable to be a true value. The example above would then look like
.PP
.Vb 4
\& # Got diag (5 bytes):
\& # abcd\ex{20}
\& # Expected diag (4 bytes):
\& # abcd
.Ve
.SH COLOUR
.IX Header "COLOUR"
If you prefer to use colour as a means of finding tricky whitespace
characters then you can set the \f(CW\*(C`TESTTESTCOLOUR\*(C'\fR environment variable to a
comma separated pair of colours, the first for the foreground, the second
for the background. For example "white,red" will print white text on a red
background. This requires the Term::ANSIColor module. You can specify any
colour that would be acceptable to the Term::ANSIColor::color function.
.PP
If you spell colour differently, that's no problem. The \f(CW\*(C`TESTTESTERCOLOR\*(C'\fR
variable also works (if both are set then the British spelling wins out).
.SH "EXPORTED FUNCTIONS"
.IX Header "EXPORTED FUNCTIONS"
\fI($premature, \fR\f(CI@results\fR\fI) = run_tests(\e&test_sub)\fR
.IX Subsection "($premature, @results) = run_tests(&test_sub)"
.PP
\&\e&test_sub is a reference to a subroutine.
.PP
run_tests runs the subroutine in \f(CW$test_sub\fR and captures the results of any
tests inside it. You can run more than 1 test inside this subroutine if you
like.
.PP
\&\f(CW$premature\fR is a string containing any diagnostic output from before
the first test.
.PP
\&\f(CW@results\fR is an array of test result hashes.
.PP
\fIcmp_result(\e%result, \e%expect, \fR\f(CI$name\fR\fI)\fR
.IX Subsection "cmp_result(%result, %expect, $name)"
.PP
\&\e%result is a ref to a test result hash.
.PP
\&\e%expect is a ref to a hash of expected values for the test result.
.PP
cmp_result compares the result with the expected values. If any differences
are found it outputs diagnostics. You may leave out any field from the
expected result and cmp_result will not do the comparison of that field.
.PP
\fIcmp_results(\e@results, \e@expects, \fR\f(CI$name\fR\fI)\fR
.IX Subsection "cmp_results(@results, @expects, $name)"
.PP
\&\e@results is a ref to an array of test results.
.PP
\&\e@expects is a ref to an array of hash refs.
.PP
cmp_results checks that the results match the expected results and if any
differences are found it outputs diagnostics. It first checks that the
number of elements in \e@results and \e@expects is the same. Then it goes
through each result checking it against the expected result as in
\&\fBcmp_result()\fR above.
.PP
\fI($premature, \fR\f(CI@results\fR\fI) = check_tests(\e&test_sub, \e@expects, \fR\f(CI$name\fR\fI)\fR
.IX Subsection "($premature, @results) = check_tests(&test_sub, @expects, $name)"
.PP
\&\e&test_sub is a reference to a subroutine.
.PP
\&\e@expect is a ref to an array of hash refs which are expected test results.
.PP
check_tests combines run_tests and cmp_tests into a single call. It also
checks if the tests died at any stage.
.PP
It returns the same values as run_tests, so you can further examine the test
results if you need to.
.PP
\fI($premature, \fR\f(CI@results\fR\fI) = check_test(\e&test_sub, \e%expect, \fR\f(CI$name\fR\fI)\fR
.IX Subsection "($premature, @results) = check_test(&test_sub, %expect, $name)"
.PP
\&\e&test_sub is a reference to a subroutine.
.PP
\&\e%expect is a ref to an hash of expected values for the test result.
.PP
check_test is a wrapper around check_tests. It combines run_tests and
cmp_tests into a single call, checking if the test died. It assumes
that only a single test is run inside \e&test_sub and include a test to
make sure this is true.
.PP
It returns the same values as run_tests, so you can further examine the test
results if you need to.
.PP
\fR\f(BIshow_space()\fR\fI\fR
.IX Subsection "show_space()"
.PP
Turn on the escaping of characters as described in the SPACES AND TABS
section.
.SH "HOW IT WORKS"
.IX Header "HOW IT WORKS"
Normally, a test module (let's call it Test:MyStyle) calls
Test::Builder\->new to get the Test::Builder object. Test::MyStyle calls
methods on this object to record information about test results. When
Test::Tester is loaded, it replaces Test::Builder's \fBnew()\fR method with one
which returns a Test::Tester::Delegate object. Most of the time this object
behaves as the real Test::Builder object. Any methods that are called are
delegated to the real Test::Builder object so everything works perfectly.
However once we go into test mode, the method calls are no longer passed to
the real Test::Builder object, instead they go to the Test::Tester::Capture
object. This object seems exactly like the real Test::Builder object,
except, instead of outputting test results and diagnostics, it just records
all the information for later analysis.
.SH CAVEATS
.IX Header "CAVEATS"
Support for calling Test::Builder\->note is minimal. It's implemented
as an empty stub, so modules that use it will not crash but the calls
are not recorded for testing purposes like the others. Patches
welcome.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Test::Builder the source of testing goodness. Test::Builder::Tester
for an alternative approach to the problem tackled by Test::Tester \-
captures the strings output by Test::Builder. This means you cannot get
separate access to the individual pieces of information and you must predict
\&\fBexactly\fR what your test will output.
.SH AUTHOR
.IX Header "AUTHOR"
This module is copyright 2005 Fergal Daly <fergal@esatclear.ie>, some parts
are based on other people's work.
.PP
Plan handling lifted from Test::More. written by Michael G Schwern
<schwern@pobox.com>.
.PP
Test::Tester::Capture is a cut down and hacked up version of Test::Builder.
Test::Builder was written by chromatic <chromatic@wgz.org> and Michael G
Schwern <schwern@pobox.com>.
.SH LICENSE
.IX Header "LICENSE"
Under the same license as Perl itself
.PP
See http://www.perl.com/perl/misc/Artistic.html
|