forked from Test-More/Test2-Harness
-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
554 lines (353 loc) · 16.4 KB
/
README
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
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
NAME
App::Yath - Yet Another Test Harness (Test2-Harness) Command Line
Interface (CLI)
DESCRIPTION
This is the primary documentation for yath, App::Yath, Test2::Harness.
The canonical source of up-to-date command options are the help output
when using $ yath help and $ yath help COMMAND.
This document is mainly an overview of yath usage and common recipes.
App::Yath is an alternative to App::Prove, and Test2::Harness is an
alternative to Test::Harness. It is not designed to replace
Test::Harness/prove. Test2::Harness is designed to take full advantage
of the rich data Test2 can provide. Test2::Harness is also able to use
non-core modules and provide more functionality than prove can achieve
with its restrictions.
PLATFORM SUPPORT
Test2::Harness/App::Yath is is focused on unix-like platforms. Most
development happens on linux, but bsd, macos, etc should work fine as
well.
Patches are welcome for any/all platforms, but the primary author (Chad
'Exodist' Granum) does not directly develop against non-unix platforms.
WINDOWS
Currently windows is not supported, and it is known that the package
will not install on windows. Patches are be welcome, and it would be
great if someone wanted to take on the windows-support role, but it is
not a primary goal for the project.
OVERVIEW
To use Test2::Harness, you use the yath command. Yath will find the
tests (or use the ones you specify) and run them. As it runs, it will
output diagnostic information such as failures. At the end, yath will
print a summary of the test run.
yath can be thought of as a more powerful alternative to prove
(Test::Harness)
RECIPES
These are common recipes for using yath.
RUN PROJECT TESTS
$ yath
Simply running yath with no arguments means "Run all tests for the
current project". Yath will look for tests in ./t, ./t2, and ./test.pl
and run any which are found.
Normally this implies the test command but will instead imply the run
command if a persistent test runner is detected.
PRELOAD MODULES
Yath has the ability to preload modules. Yath normally forks to start
new tests, so preloading can reduce the time spent loading modules over
and over in each test.
Note that some tests may depend on certain modules not being loaded. In
these cases you can add the # HARNESS-NO-PRELOAD directive to the top
of the test files that cannot use preload.
SIMPLE PRELOAD
Any module can be preloaded:
$ yath -PMoose
You can preload as many modules as you want:
$ yath -PList::Util -PScalar::Util
COMPLEX PRELOAD
If your preload is a subclass of Test2::Harness::Runner::Preload then
more complex preload behavior is possible. See those docs for more
info.
LOGGING
RECORDING A LOG
You can turn on logging with a flag. The filename of the log will be
printed at the end.
$ yath -L
...
Wrote log file: test-logs/2017-09-12~22:44:34~1505281474~25709.jsonl
The event log can be quite large. It can be compressed with bzip2.
$ yath -B
...
Wrote log file: test-logs/2017-09-12~22:44:34~1505281474~25709.jsonl.bz2
gzip compression is also supported.
$ yath -G
...
Wrote log file: test-logs/2017-09-12~22:44:34~1505281474~25709.jsonl.gz
-B and -G both imply -L.
REPLAYING FROM A LOG
You can replay a test run from a log file:
$ yath test-logs/2017-09-12~22:44:34~1505281474~25709.jsonl.bz2
This will be significantly faster than the initial run as no tests are
actually being executed. All events are simply read from the log, and
processed by the harness.
You can change display options and limit rendering/processing to
specific test jobs from the run:
$ yath test-logs/2017-09-12~22:44:34~1505281474~25709.jsonl.bz2 -v [TEST UUID(S)]
Note: This is done using the $ yath replay ... command. The replay
command is implied if the first argument is a log file.
PER-TEST TIMING DATA
The -T option will cause each test file to report how long it took to
run.
$ yath -T
( PASSED ) job 1 t/yath_script.t
( TIME ) job 1 Startup: 0.07692s | Events: 0.01170s | Cleanup: 0.00190s | Total: 0.09052s
PERSISTENT RUNNER
yath supports starting a yath session that waits for tests to run. This
is very useful when combined with preload.
STARTING
This starts the server. Many options available to the 'test' command
will work here but not all. See $ yath help start for more info.
$ yath start
RUNNING
This will run tests using the persistent runner. By default, it will
search for tests just like the 'test' command. Many options available
to the test command will work for this as well. See $ yath help run for
more details.
$ yath run
STOPPING
Stopping a persistent runner is easy.
$ yath stop
INFORMATIONAL
The which command will tell you which persistent runner will be used.
Yath searches for the persistent runner in the current directory, then
searches in parent directories until it either hits the root directory,
or finds the persistent runner tracking file.
$ yath which
The watch command will tail the runner's log files.
$ yath watch
PRELOAD + PERSISTENT RUNNER
You can use preloads with the yath start command. In this case, yath
will track all the modules pulled in during preload. If any of them
change, the server will reload itself to bring in the changes. Further,
modified modules will be blacklisted so that they are not preloaded on
subsequent reloads. This behavior is useful if you are actively working
on a module that is normally preloaded.
MAKING YOUR PROJECT ALWAYS USE YATH
$ yath init
The above command will create test.pl. test.pl is automatically run by
most build utils, in which case only the exit value matters. The
generated test.pl will run yath and execute all tests in the ./t and/or
./t2 directories. Tests in ./t will ALSO be run by prove but tests in
./t2 will only be run by yath.
PROJECT-SPECIFIC YATH CONFIG
You can write a .yath.rc file. The file format is very simple. Create a
[COMMAND] section to start the configuration for a command and then
provide any options normally allowed by it. When yath is run inside
your project, it will use the config specified in the rc file, unless
overridden by command line options.
Note: You can also add pre-command options by placing them at the top
of your config file BEFORE any [cmd] markers.
Comments start with a semi-colon.
Example .yath.rc:
-pFoo ; Load the 'foo' plugin before dealing with commands.
[test]
-B ;Always write a bzip2-compressed log
[start]
-PMoose ;Always preload Moose with a persistent runner
This file is normally committed into the project's repo.
SPECIAL PATH PSEUDO-FUNCTIONS
Sometimes you want to specify files relative to the .yath.rc so that
the config option works from any subdirectory of the project. Other
times you may wish to use a shell expansion. Sometimes you want both!
rel(path/to/file)
-I rel(path/to/extra_lib)
-I=rel(path/to/extra_lib)
This will take the path to .yath.rc and prefix it to the path inside
rel(...). If for example you have /project/.yath.rc then the path
would become /project/path/to/extra_lib.
glob(path/*/file)
--default-search glob(subprojects/*/t)
--default-search=glob(subprojects/*/t)
This will add a --default-search $_ for every item found in the glob.
This uses the perl builtin function glob() under the hood.
relglob(path/*/file)
--default-search relglob(subprojects/*/t)
--default-search=relglob(subprojects/*/t)
Same as glob() except paths are relative to the .yath.rc file.
PROJECT-SPECIFIC YATH CONFIG USER OVERRIDES
You can add a .yath.user.rc file. Format is the same as the regular
.yath.rc file. This file will be read in addition to the regular config
file. Directives in this file will come AFTER the directives in the
primary config so it may be used to override config.
This file should not normally be committed to the project repo.
HARNESS DIRECTIVES INSIDE TESTS
yath will recognise a number of directive comments placed near the top
of test files. These directives should be placed after the #! line but
before any real code.
Real code is defined as any line that does not start with use, require,
BEGIN, package, or #
good example 1
#!/usr/bin/perl
# HARNESS-NO-FORK
...
good example 2
#!/usr/bin/perl
use strict;
use warnings;
# HARNESS-NO-FORK
...
bad example 1
#!/usr/bin/perl
# blah
# HARNESS-NO-FORK
...
bad example 2
#!/usr/bin/perl
print "hi\n";
# HARNESS-NO-FORK
...
HARNESS-NO-PRELOAD
#!/usr/bin/perl
# HARNESS-NO-PRELOAD
Use this if your test will fail when modules are preloaded. This will
tell yath to start a new perl process to run the script instead of
forking with preloaded modules.
Currently this implies HARNESS-NO-FORK, but that may not always be the
case.
HARNESS-NO-FORK
#!/usr/bin/perl
# HARNESS-NO-FORK
Use this if your test file cannot run in a forked process, but instead
must be run directly with a new perl process.
This implies HARNESS-NO-PRELOAD.
HARNESS-NO-STREAM
yath usually uses the Test2::Formatter::Stream formatter instead of
TAP. Some tests depend on using a TAP formatter. This option will make
yath use Test2::Formatter::TAP or Test::Builder::Formatter.
HARNESS-NO-IO-EVENTS
yath can be configured to use the Test2::Plugin::IOEvents plugin. This
plugin replaces STDERR and STDOUT in your test with tied handles that
fire off proper Test2::Event's when they are printed to. Most of the
time this is not an issue, but any fancy tests or modules which do
anything with STDERR or STDOUT other than print may have really messy
errors.
Note: This plugin is disabled by default, so you only need this
directive if you enable it globally but need to turn it back off for
select tests.
HARNESS-NO-TIMEOUT
yath will usually kill a test if no events occur within a timeout
(default 60 seconds). You can add this directive to tests that are
expected to trip the timeout, but should be allowed to continue.
NOTE: you usually are doing the wrong thing if you need to set this.
See: HARNESS-TIMEOUT-EVENT.
HARNESS-TIMEOUT-EVENT 60
yath can be told to alter the default event timeout from 60 seconds to
another value. This is the recommended alternative to
HARNESS-NO-TIMEOUT
HARNESS-TIMEOUT-POSTEXIT 15
yath can be told to alter the default POSTEXIT timeout from 15 seconds
to another value.
Sometimes a test will fork producing output in the child while the
parent is allowed to exit. In these cases we cannot rely on the
original process exit to tell us when a test is complete. In cases
where we have an exit, and partial output (assertions with no final
plan, or a plan that has not been completed) we wait for a timeout
period to see if any additional events come into
HARNESS-DURATION-LONG
This lets you tell yath that the test file is long-running. This is
primarily used when concurrency is turned on in order to run longer
tests earlier, and concurrently with shorter ones. There is also a yath
option to skip all long tests.
This duration is set automatically if HARNESS-NO-TIMEOUT is set.
HARNESS-DURATION-MEDIUM
This lets you tell yath that the test is medium.
This is the default duration.
HARNESS-DURATION-SHORT
This lets you tell yath That the test is short.
HARNESS-CATEGORY-ISOLATION
This lets you tell yath that the test cannot be run concurrently with
other tests. Yath will hold off and run these tests one at a time after
all other tests.
HARNESS-CATEGORY-IMMISCIBLE
This lets you tell yath that the test cannot be run concurrently with
other tests of this class. This is helpful when you have multiple tests
which would otherwise have to be run sequentially at the end of the
run.
Yath prioritizes running these tests above HARNESS-CATEGORY-LONG.
HARNESS-CATEGORY-GENERAL
This is the default category.
HARNESS-CONFLICTS-XXX
This lets you tell yath that no other test of type XXX can be run at
the same time as this one. You are able to set multiple conflict types
and yath will honor them.
XXX can be replaced with any type of your choosing.
NOTE: This directive does not alter the category of your test. You are
free to mark the test with LONG or MEDIUM in addition to this marker.
HARNESS-JOB-SLOTS 2
HARNESS-JOB-SLOTS 1 10
Specify a range of job slots needed for the test to run. If set to a
single value then the test will only run if it can have the specified
number of slots. If given a range the test will require at least the
lower number of slots, and use up to the maximum number of slots.
Example with multiple lines.
#!/usr/bin/perl
# DASH and space are split the same way.
# HARNESS-CONFLICTS-DAEMON
# HARNESS-CONFLICTS MYSQL
...
Or on a single line.
#!/usr/bin/perl
# HARNESS-CONFLICTS DAEMON MYSQL
...
HARNESS-RETRY-n
This lets you specify a number (minimum n=1) of retries on test failure
for a specific test. HARNESS-RETRY-1 means a failing test will be run
twice and is equivalent to HARNESS-RETRY.
HARNESS-NO-RETRY
Use this to avoid this test being retried regardless of your retry
settings.
MODULE DOCS
This section documents the App::Yath module itself.
SYNOPSIS
In practice you should never need to write your own yath script, or
construct an App::Yath instance, or even access themain instance when
yath is running. However some aspects of doing so are documented here
for completeness.
A minimum yath script looks like this:
BEGIN {
package App::Yath:Script;
require Time::HiRes;
require App::Yath;
require Test2::Harness::Settings;
my $settings = Test2::Harness::Settings->new(
harness => {
orig_argv => [@ARGV],
orig_inc => [@INC],
script => __FILE__,
start => Time::HiRes::time(),
version => $App::Yath::VERSION,
},
);
my $app = App::Yath->new(
argv => \@ARGV,
config => {},
settings => $settings,
);
$app->generate_run_sub('App::Yath::Script::run');
}
exit(App::Yath::Script::run());
It is important that most logic live in a BEGIN block. This is so that
goto::file can be used post-fork to execute a test script.
The actual yath script is significantly more complicated with the
following behaviors:
pre-process essential arguments such as -D and no-scan-plugins
re-exec with a different yath script if in developer mode and a local
copy is found
Parse the yath-rc config files
gather and store essential startup information
METHODS
App::Yath does not provide many methods to use externally.
$app->generate_run_sub($symbol_name)
This tells App::Yath to generate a subroutine at the specified symbol
name which can be run and be expected to return an exit value.
$lib_path = $app->app_path()
Get the include directory App::Yath was loaded from.
SOURCE
The source code repository for Test2-Harness can be found at
http://github.com/Test-More/Test2-Harness/.
MAINTAINERS
Chad Granum <[email protected]>
AUTHORS
Chad Granum <[email protected]>
COPYRIGHT
Copyright 2020 Chad Granum <[email protected]>.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
See http://dev.perl.org/licenses/