diff options
Diffstat (limited to 'upstream/debian-unstable/man3/Test::Tutorial.3perl')
-rw-r--r-- | upstream/debian-unstable/man3/Test::Tutorial.3perl | 683 |
1 files changed, 683 insertions, 0 deletions
diff --git a/upstream/debian-unstable/man3/Test::Tutorial.3perl b/upstream/debian-unstable/man3/Test::Tutorial.3perl new file mode 100644 index 00000000..1d8c4cf2 --- /dev/null +++ b/upstream/debian-unstable/man3/Test::Tutorial.3perl @@ -0,0 +1,683 @@ +.\" -*- 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::Tutorial 3perl" +.TH Test::Tutorial 3perl 2024-01-12 "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::Tutorial \- A tutorial about writing really basic tests +.SH DESCRIPTION +.IX Header "DESCRIPTION" +\&\fIAHHHHHHH!!!! NOT TESTING! Anything but testing! +Beat me, whip me, send me to Detroit, but don't make +me write tests!\fR +.PP +\&\fI*sob*\fR +.PP +\&\fIBesides, I don't know how to write the damned things.\fR +.PP +Is this you? Is writing tests right up there with writing +documentation and having your fingernails pulled out? Did you open up +a test and read +.PP +.Vb 1 +\& ######## We start with some black magic +.Ve +.PP +and decide that's quite enough for you? +.PP +It's ok. That's all gone now. We've done all the black magic for +you. And here are the tricks... +.SS "Nuts and bolts of testing." +.IX Subsection "Nuts and bolts of testing." +Here's the most basic test program. +.PP +.Vb 1 +\& #!/usr/bin/perl \-w +\& +\& print "1..1\en"; +\& +\& print 1 + 1 == 2 ? "ok 1\en" : "not ok 1\en"; +.Ve +.PP +Because 1 + 1 is 2, it prints: +.PP +.Vb 2 +\& 1..1 +\& ok 1 +.Ve +.PP +What this says is: \f(CW1..1\fR "I'm going to run one test." [1] \f(CW\*(C`ok 1\*(C'\fR +"The first test passed". And that's about all magic there is to +testing. Your basic unit of testing is the \fIok\fR. For each thing you +test, an \f(CW\*(C`ok\*(C'\fR is printed. Simple. Test::Harness interprets your test +results to determine if you succeeded or failed (more on that later). +.PP +Writing all these print statements rapidly gets tedious. Fortunately, +there's Test::Simple. It has one function, \f(CWok()\fR. +.PP +.Vb 1 +\& #!/usr/bin/perl \-w +\& +\& use Test::Simple tests => 1; +\& +\& ok( 1 + 1 == 2 ); +.Ve +.PP +That does the same thing as the previous code. \f(CWok()\fR is the backbone +of Perl testing, and we'll be using it instead of roll-your-own from +here on. If \f(CWok()\fR gets a true value, the test passes. False, it +fails. +.PP +.Vb 1 +\& #!/usr/bin/perl \-w +\& +\& use Test::Simple tests => 2; +\& ok( 1 + 1 == 2 ); +\& ok( 2 + 2 == 5 ); +.Ve +.PP +From that comes: +.PP +.Vb 5 +\& 1..2 +\& ok 1 +\& not ok 2 +\& # Failed test (test.pl at line 5) +\& # Looks like you failed 1 tests of 2. +.Ve +.PP +\&\f(CW1..2\fR "I'm going to run two tests." This number is a \fIplan\fR. It helps to +ensure your test program ran all the way through and didn't die or skip some +tests. \f(CW\*(C`ok 1\*(C'\fR "The first test passed." \f(CW\*(C`not ok 2\*(C'\fR "The second test failed". +Test::Simple helpfully prints out some extra commentary about your tests. +.PP +It's not scary. Come, hold my hand. We're going to give an example +of testing a module. For our example, we'll be testing a date +library, Date::ICal. It's on CPAN, so download a copy and follow +along. [2] +.SS "Where to start?" +.IX Subsection "Where to start?" +This is the hardest part of testing, where do you start? People often get +overwhelmed at the apparent enormity of the task of testing a whole module. +The best place to start is at the beginning. Date::ICal is an +object-oriented module, and that means you start by making an object. Test +\&\f(CWnew()\fR. +.PP +.Vb 1 +\& #!/usr/bin/perl \-w +\& +\& # assume these two lines are in all subsequent examples +\& use strict; +\& use warnings; +\& +\& use Test::Simple tests => 2; +\& +\& use Date::ICal; +\& +\& my $ical = Date::ICal\->new; # create an object +\& ok( defined $ical ); # check that we got something +\& ok( $ical\->isa(\*(AqDate::ICal\*(Aq) ); # and it\*(Aqs the right class +.Ve +.PP +Run that and you should get: +.PP +.Vb 3 +\& 1..2 +\& ok 1 +\& ok 2 +.Ve +.PP +Congratulations! You've written your first useful test. +.SS Names +.IX Subsection "Names" +That output isn't terribly descriptive, is it? When you have two tests you can +figure out which one is #2, but what if you have 102 tests? +.PP +Each test can be given a little descriptive name as the second +argument to \f(CWok()\fR. +.PP +.Vb 1 +\& use Test::Simple tests => 2; +\& +\& ok( defined $ical, \*(Aqnew() returned something\*(Aq ); +\& ok( $ical\->isa(\*(AqDate::ICal\*(Aq), " and it\*(Aqs the right class" ); +.Ve +.PP +Now you'll see: +.PP +.Vb 3 +\& 1..2 +\& ok 1 \- new() returned something +\& ok 2 \- and it\*(Aqs the right class +.Ve +.SS "Test the manual" +.IX Subsection "Test the manual" +The simplest way to build up a decent testing suite is to just test what +the manual says it does. [3] Let's pull something out of the +"SYNOPSIS" in Date::ICal and test that all its bits work. +.PP +.Vb 1 +\& #!/usr/bin/perl \-w +\& +\& use Test::Simple tests => 8; +\& +\& use Date::ICal; +\& +\& $ical = Date::ICal\->new( year => 1964, month => 10, day => 16, +\& hour => 16, min => 12, sec => 47, +\& tz => \*(Aq0530\*(Aq ); +\& +\& ok( defined $ical, \*(Aqnew() returned something\*(Aq ); +\& ok( $ical\->isa(\*(AqDate::ICal\*(Aq), " and it\*(Aqs the right class" ); +\& ok( $ical\->sec == 47, \*(Aq sec()\*(Aq ); +\& ok( $ical\->min == 12, \*(Aq min()\*(Aq ); +\& ok( $ical\->hour == 16, \*(Aq hour()\*(Aq ); +\& ok( $ical\->day == 17, \*(Aq day()\*(Aq ); +\& ok( $ical\->month == 10, \*(Aq month()\*(Aq ); +\& ok( $ical\->year == 1964, \*(Aq year()\*(Aq ); +.Ve +.PP +Run that and you get: +.PP +.Vb 11 +\& 1..8 +\& ok 1 \- new() returned something +\& ok 2 \- and it\*(Aqs the right class +\& ok 3 \- sec() +\& ok 4 \- min() +\& ok 5 \- hour() +\& not ok 6 \- day() +\& # Failed test (\- at line 16) +\& ok 7 \- month() +\& ok 8 \- year() +\& # Looks like you failed 1 tests of 8. +.Ve +.PP +Whoops, a failure! [4] Test::Simple helpfully lets us know on what line the +failure occurred, but not much else. We were supposed to get 17, but we +didn't. What did we get?? Dunno. You could re-run the test in the debugger +or throw in some print statements to find out. +.PP +Instead, switch from Test::Simple to Test::More. Test::More +does everything Test::Simple does, and more! In fact, Test::More does +things \fIexactly\fR the way Test::Simple does. You can literally swap +Test::Simple out and put Test::More in its place. That's just what +we're going to do. +.PP +Test::More does more than Test::Simple. The most important difference at +this point is it provides more informative ways to say "ok". Although you can +write almost any test with a generic \f(CWok()\fR, it can't tell you what went +wrong. The \f(CWis()\fR function lets us declare that something is supposed to be +the same as something else: +.PP +.Vb 1 +\& use Test::More tests => 8; +\& +\& use Date::ICal; +\& +\& $ical = Date::ICal\->new( year => 1964, month => 10, day => 16, +\& hour => 16, min => 12, sec => 47, +\& tz => \*(Aq0530\*(Aq ); +\& +\& ok( defined $ical, \*(Aqnew() returned something\*(Aq ); +\& ok( $ical\->isa(\*(AqDate::ICal\*(Aq), " and it\*(Aqs the right class" ); +\& is( $ical\->sec, 47, \*(Aq sec()\*(Aq ); +\& is( $ical\->min, 12, \*(Aq min()\*(Aq ); +\& is( $ical\->hour, 16, \*(Aq hour()\*(Aq ); +\& is( $ical\->day, 17, \*(Aq day()\*(Aq ); +\& is( $ical\->month, 10, \*(Aq month()\*(Aq ); +\& is( $ical\->year, 1964, \*(Aq year()\*(Aq ); +.Ve +.PP +"Is \f(CW\*(C`$ical\->sec\*(C'\fR 47?" "Is \f(CW\*(C`$ical\->min\*(C'\fR 12?" With \f(CWis()\fR in place, +you get more information: +.PP +.Vb 10 +\& 1..8 +\& ok 1 \- new() returned something +\& ok 2 \- and it\*(Aqs the right class +\& ok 3 \- sec() +\& ok 4 \- min() +\& ok 5 \- hour() +\& not ok 6 \- day() +\& # Failed test (\- at line 16) +\& # got: \*(Aq16\*(Aq +\& # expected: \*(Aq17\*(Aq +\& ok 7 \- month() +\& ok 8 \- year() +\& # Looks like you failed 1 tests of 8. +.Ve +.PP +Aha. \f(CW\*(C`$ical\->day\*(C'\fR returned 16, but we expected 17. A +quick check shows that the code is working fine, we made a mistake +when writing the tests. Change it to: +.PP +.Vb 1 +\& is( $ical\->day, 16, \*(Aq day()\*(Aq ); +.Ve +.PP +\&... and everything works. +.PP +Any time you're doing a "this equals that" sort of test, use \f(CWis()\fR. +It even works on arrays. The test is always in scalar context, so you +can test how many elements are in an array this way. [5] +.PP +.Vb 1 +\& is( @foo, 5, \*(Aqfoo has 5 elements\*(Aq ); +.Ve +.SS "Sometimes the tests are wrong" +.IX Subsection "Sometimes the tests are wrong" +This brings up a very important lesson. Code has bugs. Tests are +code. Ergo, tests have bugs. A failing test could mean a bug in the +code, but don't discount the possibility that the test is wrong. +.PP +On the flip side, don't be tempted to prematurely declare a test +incorrect just because you're having trouble finding the bug. +Invalidating a test isn't something to be taken lightly, and don't use +it as a cop out to avoid work. +.SS "Testing lots of values" +.IX Subsection "Testing lots of values" +We're going to be wanting to test a lot of dates here, trying to trick +the code with lots of different edge cases. Does it work before 1970? +After 2038? Before 1904? Do years after 10,000 give it trouble? +Does it get leap years right? We could keep repeating the code above, +or we could set up a little try/expect loop. +.PP +.Vb 2 +\& use Test::More tests => 32; +\& use Date::ICal; +\& +\& my %ICal_Dates = ( +\& # An ICal string And the year, month, day +\& # hour, minute and second we expect. +\& \*(Aq19971024T120000\*(Aq => # from the docs. +\& [ 1997, 10, 24, 12, 0, 0 ], +\& \*(Aq20390123T232832\*(Aq => # after the Unix epoch +\& [ 2039, 1, 23, 23, 28, 32 ], +\& \*(Aq19671225T000000\*(Aq => # before the Unix epoch +\& [ 1967, 12, 25, 0, 0, 0 ], +\& \*(Aq18990505T232323\*(Aq => # before the MacOS epoch +\& [ 1899, 5, 5, 23, 23, 23 ], +\& ); +\& +\& +\& while( my($ical_str, $expect) = each %ICal_Dates ) { +\& my $ical = Date::ICal\->new( ical => $ical_str ); +\& +\& ok( defined $ical, "new(ical => \*(Aq$ical_str\*(Aq)" ); +\& ok( $ical\->isa(\*(AqDate::ICal\*(Aq), " and it\*(Aqs the right class" ); +\& +\& is( $ical\->year, $expect\->[0], \*(Aq year()\*(Aq ); +\& is( $ical\->month, $expect\->[1], \*(Aq month()\*(Aq ); +\& is( $ical\->day, $expect\->[2], \*(Aq day()\*(Aq ); +\& is( $ical\->hour, $expect\->[3], \*(Aq hour()\*(Aq ); +\& is( $ical\->min, $expect\->[4], \*(Aq min()\*(Aq ); +\& is( $ical\->sec, $expect\->[5], \*(Aq sec()\*(Aq ); +\& } +.Ve +.PP +Now we can test bunches of dates by just adding them to +\&\f(CW%ICal_Dates\fR. Now that it's less work to test with more dates, you'll +be inclined to just throw more in as you think of them. +Only problem is, every time we add to that we have to keep adjusting +the \f(CW\*(C`use Test::More tests => ##\*(C'\fR line. That can rapidly get +annoying. There are ways to make this work better. +.PP +First, we can calculate the plan dynamically using the \f(CWplan()\fR +function. +.PP +.Vb 2 +\& use Test::More; +\& use Date::ICal; +\& +\& my %ICal_Dates = ( +\& ...same as before... +\& ); +\& +\& # For each key in the hash we\*(Aqre running 8 tests. +\& plan tests => keys(%ICal_Dates) * 8; +\& +\& ...and then your tests... +.Ve +.PP +To be even more flexible, use \f(CW\*(C`done_testing\*(C'\fR. This means we're just +running some tests, don't know how many. [6] +.PP +.Vb 1 +\& use Test::More; # instead of tests => 32 +\& +\& ... # tests here +\& +\& done_testing(); # reached the end safely +.Ve +.PP +If you don't specify a plan, Test::More expects to see \f(CWdone_testing()\fR +before your program exits. It will warn you if you forget it. You can give +\&\f(CWdone_testing()\fR an optional number of tests you expected to run, and if the +number ran differs, Test::More will give you another kind of warning. +.SS "Informative names" +.IX Subsection "Informative names" +Take a look at the line: +.PP +.Vb 1 +\& ok( defined $ical, "new(ical => \*(Aq$ical_str\*(Aq)" ); +.Ve +.PP +We've added more detail about what we're testing and the ICal string +itself we're trying out to the name. So you get results like: +.PP +.Vb 8 +\& ok 25 \- new(ical => \*(Aq19971024T120000\*(Aq) +\& ok 26 \- and it\*(Aqs the right class +\& ok 27 \- year() +\& ok 28 \- month() +\& ok 29 \- day() +\& ok 30 \- hour() +\& ok 31 \- min() +\& ok 32 \- sec() +.Ve +.PP +If something in there fails, you'll know which one it was and that +will make tracking down the problem easier. Try to put a bit of +debugging information into the test names. +.PP +Describe what the tests test, to make debugging a failed test easier +for you or for the next person who runs your test. +.SS "Skipping tests" +.IX Subsection "Skipping tests" +Poking around in the existing Date::ICal tests, I found this in +\&\fIt/01sanity.t\fR [7] +.PP +.Vb 1 +\& #!/usr/bin/perl \-w +\& +\& use Test::More tests => 7; +\& use Date::ICal; +\& +\& # Make sure epoch time is being handled sanely. +\& my $t1 = Date::ICal\->new( epoch => 0 ); +\& is( $t1\->epoch, 0, "Epoch time of 0" ); +\& +\& # XXX This will only work on unix systems. +\& is( $t1\->ical, \*(Aq19700101Z\*(Aq, " epoch to ical" ); +\& +\& is( $t1\->year, 1970, " year()" ); +\& is( $t1\->month, 1, " month()" ); +\& is( $t1\->day, 1, " day()" ); +\& +\& # like the tests above, but starting with ical instead of epoch +\& my $t2 = Date::ICal\->new( ical => \*(Aq19700101Z\*(Aq ); +\& is( $t2\->ical, \*(Aq19700101Z\*(Aq, "Start of epoch in ICal notation" ); +\& +\& is( $t2\->epoch, 0, " and back to ICal" ); +.Ve +.PP +The beginning of the epoch is different on most non-Unix operating systems [8]. +Even though Perl smooths out the differences for the most part, certain ports +do it differently. MacPerl is one off the top of my head. [9] Rather than +putting a comment in the test and hoping someone will read the test while +debugging the failure, we can explicitly say it's never going to work and skip +the test. +.PP +.Vb 2 +\& use Test::More tests => 7; +\& use Date::ICal; +\& +\& # Make sure epoch time is being handled sanely. +\& my $t1 = Date::ICal\->new( epoch => 0 ); +\& is( $t1\->epoch, 0, "Epoch time of 0" ); +\& +\& SKIP: { +\& skip(\*(Aqepoch to ICal not working on Mac OS\*(Aq, 6) +\& if $^O eq \*(AqMacOS\*(Aq; +\& +\& is( $t1\->ical, \*(Aq19700101Z\*(Aq, " epoch to ical" ); +\& +\& is( $t1\->year, 1970, " year()" ); +\& is( $t1\->month, 1, " month()" ); +\& is( $t1\->day, 1, " day()" ); +\& +\& # like the tests above, but starting with ical instead of epoch +\& my $t2 = Date::ICal\->new( ical => \*(Aq19700101Z\*(Aq ); +\& is( $t2\->ical, \*(Aq19700101Z\*(Aq, "Start of epoch in ICal notation" ); +\& +\& is( $t2\->epoch, 0, " and back to ICal" ); +\& } +.Ve +.PP +A little bit of magic happens here. When running on anything but MacOS, all +the tests run normally. But when on MacOS, \f(CWskip()\fR causes the entire +contents of the SKIP block to be jumped over. It never runs. Instead, +\&\f(CWskip()\fR prints special output that tells Test::Harness that the tests have +been skipped. +.PP +.Vb 8 +\& 1..7 +\& ok 1 \- Epoch time of 0 +\& ok 2 # skip epoch to ICal not working on MacOS +\& ok 3 # skip epoch to ICal not working on MacOS +\& ok 4 # skip epoch to ICal not working on MacOS +\& ok 5 # skip epoch to ICal not working on MacOS +\& ok 6 # skip epoch to ICal not working on MacOS +\& ok 7 # skip epoch to ICal not working on MacOS +.Ve +.PP +This means your tests won't fail on MacOS. This means fewer emails +from MacPerl users telling you about failing tests that you know will +never work. You've got to be careful with skip tests. These are for +tests which don't work and \fInever will\fR. It is not for skipping +genuine bugs (we'll get to that in a moment). +.PP +The tests are wholly and completely skipped. [10] This will work. +.PP +.Vb 2 +\& SKIP: { +\& skip("I don\*(Aqt wanna die!"); +\& +\& die, die, die, die, die; +\& } +.Ve +.SS "Todo tests" +.IX Subsection "Todo tests" +While thumbing through the Date::ICal man page, I came across this: +.PP +.Vb 1 +\& ical +\& +\& $ical_string = $ical\->ical; +\& +\& Retrieves, or sets, the date on the object, using any +\& valid ICal date/time string. +.Ve +.PP +"Retrieves or sets". Hmmm. I didn't see a test for using \f(CWical()\fR to set +the date in the Date::ICal test suite. So I wrote one: +.PP +.Vb 2 +\& use Test::More tests => 1; +\& use Date::ICal; +\& +\& my $ical = Date::ICal\->new; +\& $ical\->ical(\*(Aq20201231Z\*(Aq); +\& is( $ical\->ical, \*(Aq20201231Z\*(Aq, \*(AqSetting via ical()\*(Aq ); +.Ve +.PP +Run that. I saw: +.PP +.Vb 6 +\& 1..1 +\& not ok 1 \- Setting via ical() +\& # Failed test (\- at line 6) +\& # got: \*(Aq20010814T233649Z\*(Aq +\& # expected: \*(Aq20201231Z\*(Aq +\& # Looks like you failed 1 tests of 1. +.Ve +.PP +Whoops! Looks like it's unimplemented. Assume you don't have the time to fix +this. [11] Normally, you'd just comment out the test and put a note in a todo +list somewhere. Instead, explicitly state "this test will fail" by wrapping it +in a \f(CW\*(C`TODO\*(C'\fR block: +.PP +.Vb 1 +\& use Test::More tests => 1; +\& +\& TODO: { +\& local $TODO = \*(Aqical($ical) not yet implemented\*(Aq; +\& +\& my $ical = Date::ICal\->new; +\& $ical\->ical(\*(Aq20201231Z\*(Aq); +\& +\& is( $ical\->ical, \*(Aq20201231Z\*(Aq, \*(AqSetting via ical()\*(Aq ); +\& } +.Ve +.PP +Now when you run, it's a little different: +.PP +.Vb 4 +\& 1..1 +\& not ok 1 \- Setting via ical() # TODO ical($ical) not yet implemented +\& # got: \*(Aq20010822T201551Z\*(Aq +\& # expected: \*(Aq20201231Z\*(Aq +.Ve +.PP +Test::More doesn't say "Looks like you failed 1 tests of 1". That '# +TODO' tells Test::Harness "this is supposed to fail" and it treats a +failure as a successful test. You can write tests even before +you've fixed the underlying code. +.PP +If a TODO test passes, Test::Harness will report it "UNEXPECTEDLY +SUCCEEDED". When that happens, remove the TODO block with \f(CW\*(C`local $TODO\*(C'\fR and +turn it into a real test. +.SS "Testing with taint mode." +.IX Subsection "Testing with taint mode." +Taint mode is a funny thing. It's the globalest of all global +features. Once you turn it on, it affects \fIall\fR code in your program +and \fIall\fR modules used (and all the modules they use). If a single +piece of code isn't taint clean, the whole thing explodes. With that +in mind, it's very important to ensure your module works under taint +mode. +.PP +It's very simple to have your tests run under taint mode. Just throw +a \f(CW\*(C`\-T\*(C'\fR into the \f(CW\*(C`#!\*(C'\fR line. Test::Harness will read the switches +in \f(CW\*(C`#!\*(C'\fR and use them to run your tests. +.PP +.Vb 1 +\& #!/usr/bin/perl \-Tw +\& +\& ...test normally here... +.Ve +.PP +When you say \f(CW\*(C`make test\*(C'\fR it will run with taint mode on. +.SH FOOTNOTES +.IX Header "FOOTNOTES" +.IP 1. 4 +The first number doesn't really mean anything, but it has to be 1. +It's the second number that's important. +.IP 2. 4 +For those following along at home, I'm using version 1.31. It has +some bugs, which is good \-\- we'll uncover them with our tests. +.IP 3. 4 +You can actually take this one step further and test the manual +itself. Have a look at Test::Inline (formerly Pod::Tests). +.IP 4. 4 +Yes, there's a mistake in the test suite. What! Me, contrived? +.IP 5. 4 +We'll get to testing the contents of lists later. +.IP 6. 4 +But what happens if your test program dies halfway through?! Since we +didn't say how many tests we're going to run, how can we know it +failed? No problem, Test::More employs some magic to catch that death +and turn the test into a failure, even if every test passed up to that +point. +.IP 7. 4 +I cleaned it up a little. +.IP 8. 4 +Most Operating Systems record time as the number of seconds since a +certain date. This date is the beginning of the epoch. Unix's starts +at midnight January 1st, 1970 GMT. +.IP 9. 4 +MacOS's epoch is midnight January 1st, 1904. VMS's is midnight, +November 17th, 1858, but vmsperl emulates the Unix epoch so it's not a +problem. +.IP 10. 4 +As long as the code inside the SKIP block at least compiles. Please +don't ask how. No, it's not a filter. +.IP 11. 4 +Do NOT be tempted to use TODO tests as a way to avoid fixing simple +bugs! +.SH AUTHORS +.IX Header "AUTHORS" +Michael G Schwern <schwern@pobox.com> and the perl-qa dancers! +.SH MAINTAINERS +.IX Header "MAINTAINERS" +.IP "Chad Granum <exodist@cpan.org>" 4 +.IX Item "Chad Granum <exodist@cpan.org>" +.SH COPYRIGHT +.IX Header "COPYRIGHT" +Copyright 2001 by Michael G Schwern <schwern@pobox.com>. +.PP +This documentation is free; you can redistribute it and/or modify it +under the same terms as Perl itself. +.PP +Irrespective of its distribution, all code examples in these files +are hereby placed into the public domain. You are permitted and +encouraged to use this code in your own programs for fun +or for profit as you see fit. A simple comment in the code giving +credit would be courteous but is not required. |