summaryrefslogtreecommitdiffstats
path: root/upstream/archlinux/man3/Test.3perl
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/archlinux/man3/Test.3perl')
-rw-r--r--upstream/archlinux/man3/Test.3perl587
1 files changed, 587 insertions, 0 deletions
diff --git a/upstream/archlinux/man3/Test.3perl b/upstream/archlinux/man3/Test.3perl
new file mode 100644
index 00000000..feadbe9b
--- /dev/null
+++ b/upstream/archlinux/man3/Test.3perl
@@ -0,0 +1,587 @@
+.\" -*- 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 3perl"
+.TH Test 3perl 2024-02-11 "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 \- provides a simple framework for writing test scripts
+.SH SYNOPSIS
+.IX Header "SYNOPSIS"
+.Vb 2
+\& use strict;
+\& use Test;
+\&
+\& # use a BEGIN block so we print our plan before MyModule is loaded
+\& BEGIN { plan tests => 14, todo => [3,4] }
+\&
+\& # load your module...
+\& use MyModule;
+\&
+\& # Helpful notes. All note\-lines must start with a "#".
+\& print "# I\*(Aqm testing MyModule version $MyModule::VERSION\en";
+\&
+\& ok(0); # failure
+\& ok(1); # success
+\&
+\& ok(0); # ok, expected failure (see todo list, above)
+\& ok(1); # surprise success!
+\&
+\& ok(0,1); # failure: \*(Aq0\*(Aq ne \*(Aq1\*(Aq
+\& ok(\*(Aqbroke\*(Aq,\*(Aqfixed\*(Aq); # failure: \*(Aqbroke\*(Aq ne \*(Aqfixed\*(Aq
+\& ok(\*(Aqfixed\*(Aq,\*(Aqfixed\*(Aq); # success: \*(Aqfixed\*(Aq eq \*(Aqfixed\*(Aq
+\& ok(\*(Aqfixed\*(Aq,qr/x/); # success: \*(Aqfixed\*(Aq =~ qr/x/
+\&
+\& ok(sub { 1+1 }, 2); # success: \*(Aq2\*(Aq eq \*(Aq2\*(Aq
+\& ok(sub { 1+1 }, 3); # failure: \*(Aq2\*(Aq ne \*(Aq3\*(Aq
+\&
+\& my @list = (0,0);
+\& ok @list, 3, "\e@list=".join(\*(Aq,\*(Aq,@list); #extra notes
+\& ok \*(Aqsegmentation fault\*(Aq, \*(Aq/(?i)success/\*(Aq; #regex match
+\&
+\& skip(
+\& $^O =~ m/MSWin/ ? "Skip if MSWin" : 0, # whether to skip
+\& $foo, $bar # arguments just like for ok(...)
+\& );
+\& skip(
+\& $^O =~ m/MSWin/ ? 0 : "Skip unless MSWin", # whether to skip
+\& $foo, $bar # arguments just like for ok(...)
+\& );
+.Ve
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+This module simplifies the task of writing test files for Perl modules,
+such that their output is in the format that
+Test::Harness expects to see.
+.SH "QUICK START GUIDE"
+.IX Header "QUICK START GUIDE"
+To write a test for your new (and probably not even done) module, create
+a new file called \fIt/test.t\fR (in a new \fIt\fR directory). If you have
+multiple test files, to test the "foo", "bar", and "baz" feature sets,
+then feel free to call your files \fIt/foo.t\fR, \fIt/bar.t\fR, and
+\&\fIt/baz.t\fR
+.SS Functions
+.IX Subsection "Functions"
+This module defines three public functions, \f(CWplan(...)\fR, \f(CWok(...)\fR,
+and \f(CWskip(...)\fR. By default, all three are exported by
+the \f(CW\*(C`use Test;\*(C'\fR statement.
+.ie n .IP plan(...) 4
+.el .IP \f(CWplan(...)\fR 4
+.IX Item "plan(...)"
+.Vb 1
+\& BEGIN { plan %theplan; }
+.Ve
+.Sp
+This should be the first thing you call in your test script. It
+declares your testing plan, how many there will be, if any of them
+should be allowed to fail, and so on.
+.Sp
+Typical usage is just:
+.Sp
+.Vb 2
+\& use Test;
+\& BEGIN { plan tests => 23 }
+.Ve
+.Sp
+These are the things that you can put in the parameters to plan:
+.RS 4
+.ie n .IP """tests => \fInumber\fR""" 4
+.el .IP "\f(CWtests => \fR\f(CInumber\fR\f(CW\fR" 4
+.IX Item "tests => number"
+The number of tests in your script.
+This means all \fBok()\fR and \fBskip()\fR calls.
+.ie n .IP """todo => [\fI1,5,14\fR]""" 4
+.el .IP "\f(CWtodo => [\fR\f(CI1,5,14\fR\f(CW]\fR" 4
+.IX Item "todo => [1,5,14]"
+A reference to a list of tests which are allowed to fail.
+See "TODO TESTS".
+.ie n .IP """onfail => sub { ... }""" 4
+.el .IP "\f(CWonfail => sub { ... }\fR" 4
+.IX Item "onfail => sub { ... }"
+.PD 0
+.ie n .IP """onfail => \e&some_sub""" 4
+.el .IP "\f(CWonfail => \e&some_sub\fR" 4
+.IX Item "onfail => &some_sub"
+.PD
+A subroutine reference to be run at the end of the test script, if
+any of the tests fail. See "ONFAIL".
+.RE
+.RS 4
+.Sp
+You must call \f(CWplan(...)\fR once and only once. You should call it
+in a \f(CW\*(C`BEGIN {...}\*(C'\fR block, like so:
+.Sp
+.Vb 1
+\& BEGIN { plan tests => 23 }
+.Ve
+.RE
+.ie n .IP ok(...) 4
+.el .IP \f(CWok(...)\fR 4
+.IX Item "ok(...)"
+.Vb 3
+\& ok(1 + 1 == 2);
+\& ok($have, $expect);
+\& ok($have, $expect, $diagnostics);
+.Ve
+.Sp
+This function is the reason for \f(CW\*(C`Test\*(C'\fR's existence. It's
+the basic function that
+handles printing "\f(CW\*(C`ok\*(C'\fR" or "\f(CW\*(C`not ok\*(C'\fR", along with the
+current test number. (That's what \f(CW\*(C`Test::Harness\*(C'\fR wants to see.)
+.Sp
+In its most basic usage, \f(CWok(...)\fR simply takes a single scalar
+expression. If its value is true, the test passes; if false,
+the test fails. Examples:
+.Sp
+.Vb 1
+\& # Examples of ok(scalar)
+\&
+\& ok( 1 + 1 == 2 ); # ok if 1 + 1 == 2
+\& ok( $foo =~ /bar/ ); # ok if $foo contains \*(Aqbar\*(Aq
+\& ok( baz($x + $y) eq \*(AqArmondo\*(Aq ); # ok if baz($x + $y) returns
+\& # \*(AqArmondo\*(Aq
+\& ok( @a == @b ); # ok if @a and @b are the same
+\& # length
+.Ve
+.Sp
+The expression is evaluated in scalar context. So the following will
+work:
+.Sp
+.Vb 4
+\& ok( @stuff ); # ok if @stuff has any
+\& # elements
+\& ok( !grep !defined $_, @stuff ); # ok if everything in @stuff
+\& # is defined.
+.Ve
+.Sp
+A special case is if the expression is a subroutine reference (in either
+\&\f(CW\*(C`sub {...}\*(C'\fR syntax or \f(CW\*(C`\e&foo\*(C'\fR syntax). In
+that case, it is executed and its value (true or false) determines if
+the test passes or fails. For example,
+.Sp
+.Vb 5
+\& ok( sub { # See whether sleep works at least passably
+\& my $start_time = time;
+\& sleep 5;
+\& time() \- $start_time >= 4
+\& });
+.Ve
+.Sp
+In its two-argument form, \f(CW\*(C`ok(\fR\f(CIarg1\fR\f(CW, \fR\f(CIarg2\fR\f(CW)\*(C'\fR compares the two
+scalar values to see if they match. They match if both are undefined,
+or if \fIarg2\fR is a regex that matches \fIarg1\fR, or if they compare equal
+with \f(CW\*(C`eq\*(C'\fR.
+.Sp
+.Vb 1
+\& # Example of ok(scalar, scalar)
+\&
+\& ok( "this", "that" ); # not ok, \*(Aqthis\*(Aq ne \*(Aqthat\*(Aq
+\& ok( "", undef ); # not ok, "" is defined
+.Ve
+.Sp
+The second argument is considered a regex if it is either a regex
+object or a string that looks like a regex. Regex objects are
+constructed with the qr// operator in recent versions of perl. A
+string is considered to look like a regex if its first and last
+characters are "/", or if the first character is "m"
+and its second and last characters are both the
+same non-alphanumeric non-whitespace character. These regexp
+.Sp
+Regex examples:
+.Sp
+.Vb 4
+\& ok( \*(AqJaffO\*(Aq, \*(Aq/Jaff/\*(Aq ); # ok, \*(AqJaffO\*(Aq =~ /Jaff/
+\& ok( \*(AqJaffO\*(Aq, \*(Aqm|Jaff|\*(Aq ); # ok, \*(AqJaffO\*(Aq =~ m|Jaff|
+\& ok( \*(AqJaffO\*(Aq, qr/Jaff/ ); # ok, \*(AqJaffO\*(Aq =~ qr/Jaff/;
+\& ok( \*(AqJaffO\*(Aq, \*(Aq/(?i)jaff/ ); # ok, \*(AqJaffO\*(Aq =~ /jaff/i;
+.Ve
+.Sp
+If either (or both!) is a subroutine reference, it is run and used
+as the value for comparing. For example:
+.Sp
+.Vb 10
+\& ok sub {
+\& open(OUT, \*(Aq>\*(Aq, \*(Aqx.dat\*(Aq) || die $!;
+\& print OUT "\ex{e000}";
+\& close OUT;
+\& my $bytecount = \-s \*(Aqx.dat\*(Aq;
+\& unlink \*(Aqx.dat\*(Aq or warn "Can\*(Aqt unlink : $!";
+\& return $bytecount;
+\& },
+\& 4
+\& ;
+.Ve
+.Sp
+The above test passes two values to \f(CW\*(C`ok(arg1, arg2)\*(C'\fR \-\- the first
+a coderef, and the second is the number 4. Before \f(CW\*(C`ok\*(C'\fR compares them,
+it calls the coderef, and uses its return value as the real value of
+this parameter. Assuming that \f(CW$bytecount\fR returns 4, \f(CW\*(C`ok\*(C'\fR ends up
+testing \f(CW\*(C`4 eq 4\*(C'\fR. Since that's true, this test passes.
+.Sp
+Finally, you can append an optional third argument, in
+\&\f(CW\*(C`ok(\fR\f(CIarg1\fR\f(CW,\fR\f(CIarg2\fR\f(CW, \fR\f(CInote\fR\f(CW)\*(C'\fR, where \fInote\fR is a string value that
+will be printed if the test fails. This should be some useful
+information about the test, pertaining to why it failed, and/or
+a description of the test. For example:
+.Sp
+.Vb 4
+\& ok( grep($_ eq \*(Aqsomething unique\*(Aq, @stuff), 1,
+\& "Something that should be unique isn\*(Aqt!\en".
+\& \*(Aq@stuff = \*(Aq.join \*(Aq, \*(Aq, @stuff
+\& );
+.Ve
+.Sp
+Unfortunately, a note cannot be used with the single argument
+style of \f(CWok()\fR. That is, if you try \f(CW\*(C`ok(\fR\f(CIarg1\fR\f(CW, \fR\f(CInote\fR\f(CW)\*(C'\fR, then
+\&\f(CW\*(C`Test\*(C'\fR will interpret this as \f(CW\*(C`ok(\fR\f(CIarg1\fR\f(CW, \fR\f(CIarg2\fR\f(CW)\*(C'\fR, and probably
+end up testing \f(CW\*(C`\fR\f(CIarg1\fR\f(CW eq \fR\f(CIarg2\fR\f(CW\*(C'\fR \-\- and that's not what you want!
+.Sp
+All of the above special cases can occasionally cause some
+problems. See "BUGS and CAVEATS".
+.ie n .IP """skip(\fIskip_if_true\fR, \fIargs...\fR)""" 4
+.el .IP "\f(CWskip(\fR\f(CIskip_if_true\fR\f(CW, \fR\f(CIargs...\fR\f(CW)\fR" 4
+.IX Item "skip(skip_if_true, args...)"
+This is used for tests that under some conditions can be skipped. It's
+basically equivalent to:
+.Sp
+.Vb 5
+\& if( $skip_if_true ) {
+\& ok(1);
+\& } else {
+\& ok( args... );
+\& }
+.Ve
+.Sp
+\&...except that the \f(CWok(1)\fR emits not just "\f(CW\*(C`ok \fR\f(CItestnum\fR\f(CW\*(C'\fR" but
+actually "\f(CW\*(C`ok \fR\f(CItestnum\fR\f(CW # \fR\f(CIskip_if_true_value\fR\f(CW\*(C'\fR".
+.Sp
+The arguments after the \fIskip_if_true\fR are what is fed to \f(CWok(...)\fR if
+this test isn't skipped.
+.Sp
+Example usage:
+.Sp
+.Vb 2
+\& my $if_MSWin =
+\& $^O =~ m/MSWin/ ? \*(AqSkip if under MSWin\*(Aq : \*(Aq\*(Aq;
+\&
+\& # A test to be skipped if under MSWin (i.e., run except under
+\& # MSWin)
+\& skip($if_MSWin, thing($foo), thing($bar) );
+.Ve
+.Sp
+Or, going the other way:
+.Sp
+.Vb 2
+\& my $unless_MSWin =
+\& $^O =~ m/MSWin/ ? \*(Aq\*(Aq : \*(AqSkip unless under MSWin\*(Aq;
+\&
+\& # A test to be skipped unless under MSWin (i.e., run only under
+\& # MSWin)
+\& skip($unless_MSWin, thing($foo), thing($bar) );
+.Ve
+.Sp
+The tricky thing to remember is that the first parameter is true if
+you want to \fIskip\fR the test, not \fIrun\fR it; and it also doubles as a
+note about why it's being skipped. So in the first codeblock above, read
+the code as "skip if MSWin \-\- (otherwise) test whether \f(CWthing($foo)\fR is
+\&\f(CWthing($bar)\fR" or for the second case, "skip unless MSWin...".
+.Sp
+Also, when your \fIskip_if_reason\fR string is true, it really should (for
+backwards compatibility with older Test.pm versions) start with the
+string "Skip", as shown in the above examples.
+.Sp
+Note that in the above cases, \f(CWthing($foo)\fR and \f(CWthing($bar)\fR
+\&\fIare\fR evaluated \-\- but as long as the \f(CW\*(C`skip_if_true\*(C'\fR is true,
+then we \f(CWskip(...)\fR just tosses out their value (i.e., not
+bothering to treat them like values to \f(CWok(...)\fR. But if
+you need to \fInot\fR eval the arguments when skipping the
+test, use
+this format:
+.Sp
+.Vb 7
+\& skip( $unless_MSWin,
+\& sub {
+\& # This code returns true if the test passes.
+\& # (But it doesn\*(Aqt even get called if the test is skipped.)
+\& thing($foo) eq thing($bar)
+\& }
+\& );
+.Ve
+.Sp
+or even this, which is basically equivalent:
+.Sp
+.Vb 3
+\& skip( $unless_MSWin,
+\& sub { thing($foo) }, sub { thing($bar) }
+\& );
+.Ve
+.Sp
+That is, both are like this:
+.Sp
+.Vb 7
+\& if( $unless_MSWin ) {
+\& ok(1); # but it actually appends "# $unless_MSWin"
+\& # so that Test::Harness can tell it\*(Aqs a skip
+\& } else {
+\& # Not skipping, so actually call and evaluate...
+\& ok( sub { thing($foo) }, sub { thing($bar) } );
+\& }
+.Ve
+.SH "TEST TYPES"
+.IX Header "TEST TYPES"
+.IP \(bu 4
+NORMAL TESTS
+.Sp
+These tests are expected to succeed. Usually, most or all of your tests
+are in this category. If a normal test doesn't succeed, then that
+means that something is \fIwrong\fR.
+.IP \(bu 4
+SKIPPED TESTS
+.Sp
+The \f(CWskip(...)\fR function is for tests that might or might not be
+possible to run, depending
+on the availability of platform-specific features. The first argument
+should evaluate to true (think "yes, please skip") if the required
+feature is \fInot\fR available. After the first argument, \f(CWskip(...)\fR works
+exactly the same way as \f(CWok(...)\fR does.
+.IP \(bu 4
+TODO TESTS
+.Sp
+TODO tests are designed for maintaining an \fBexecutable TODO list\fR.
+These tests are \fIexpected to fail.\fR If a TODO test does succeed,
+then the feature in question shouldn't be on the TODO list, now
+should it?
+.Sp
+Packages should NOT be released with succeeding TODO tests. As soon
+as a TODO test starts working, it should be promoted to a normal test,
+and the newly working feature should be documented in the release
+notes or in the change log.
+.SH ONFAIL
+.IX Header "ONFAIL"
+.Vb 1
+\& BEGIN { plan test => 4, onfail => sub { warn "CALL 911!" } }
+.Ve
+.PP
+Although test failures should be enough, extra diagnostics can be
+triggered at the end of a test run. \f(CW\*(C`onfail\*(C'\fR is passed an array ref
+of hash refs that describe each test failure. Each hash will contain
+at least the following fields: \f(CW\*(C`package\*(C'\fR, \f(CW\*(C`repetition\*(C'\fR, and
+\&\f(CW\*(C`result\*(C'\fR. (You shouldn't rely on any other fields being present.) If the test
+had an expected value or a diagnostic (or "note") string, these will also be
+included.
+.PP
+The \fIoptional\fR \f(CW\*(C`onfail\*(C'\fR hook might be used simply to print out the
+version of your package and/or how to report problems. It might also
+be used to generate extremely sophisticated diagnostics for a
+particularly bizarre test failure. However it's not a panacea. Core
+dumps or other unrecoverable errors prevent the \f(CW\*(C`onfail\*(C'\fR hook from
+running. (It is run inside an \f(CW\*(C`END\*(C'\fR block.) Besides, \f(CW\*(C`onfail\*(C'\fR is
+probably over-kill in most cases. (Your test code should be simpler
+than the code it is testing, yes?)
+.SH "BUGS and CAVEATS"
+.IX Header "BUGS and CAVEATS"
+.IP \(bu 4
+\&\f(CWok(...)\fR's special handing of strings which look like they might be
+regexes can also cause unexpected behavior. An innocent:
+.Sp
+.Vb 1
+\& ok( $fileglob, \*(Aq/path/to/some/*stuff/\*(Aq );
+.Ve
+.Sp
+will fail, since Test.pm considers the second argument to be a regex!
+The best bet is to use the one-argument form:
+.Sp
+.Vb 1
+\& ok( $fileglob eq \*(Aq/path/to/some/*stuff/\*(Aq );
+.Ve
+.IP \(bu 4
+\&\f(CWok(...)\fR's use of string \f(CW\*(C`eq\*(C'\fR can sometimes cause odd problems
+when comparing
+numbers, especially if you're casting a string to a number:
+.Sp
+.Vb 2
+\& $foo = "1.0";
+\& ok( $foo, 1 ); # not ok, "1.0" ne 1
+.Ve
+.Sp
+Your best bet is to use the single argument form:
+.Sp
+.Vb 1
+\& ok( $foo == 1 ); # ok "1.0" == 1
+.Ve
+.IP \(bu 4
+As you may have inferred from the above documentation and examples,
+\&\f(CW\*(C`ok\*(C'\fR's prototype is \f(CW\*(C`($;$$)\*(C'\fR (and, incidentally, \f(CW\*(C`skip\*(C'\fR's is
+\&\f(CW\*(C`($;$$$)\*(C'\fR). This means, for example, that you can do \f(CW\*(C`ok @foo, @bar\*(C'\fR
+to compare the \fIsize\fR of the two arrays. But don't be fooled into
+thinking that \f(CW\*(C`ok @foo, @bar\*(C'\fR means a comparison of the contents of two
+arrays \-\- you're comparing \fIjust\fR the number of elements of each. It's
+so easy to make that mistake in reading \f(CW\*(C`ok @foo, @bar\*(C'\fR that you might
+want to be very explicit about it, and instead write \f(CWok scalar(@foo),
+scalar(@bar)\fR.
+.IP \(bu 4
+This almost definitely doesn't do what you expect:
+.Sp
+.Vb 1
+\& ok $thingy\->can(\*(Aqsome_method\*(Aq);
+.Ve
+.Sp
+Why? Because \f(CW\*(C`can\*(C'\fR returns a coderef to mean "yes it can (and the
+method is this...)", and then \f(CW\*(C`ok\*(C'\fR sees a coderef and thinks you're
+passing a function that you want it to call and consider the truth of
+the result of! I.e., just like:
+.Sp
+.Vb 1
+\& ok $thingy\->can(\*(Aqsome_method\*(Aq)\->();
+.Ve
+.Sp
+What you probably want instead is this:
+.Sp
+.Vb 1
+\& ok $thingy\->can(\*(Aqsome_method\*(Aq) && 1;
+.Ve
+.Sp
+If the \f(CW\*(C`can\*(C'\fR returns false, then that is passed to \f(CW\*(C`ok\*(C'\fR. If it
+returns true, then the larger expression \f(CW\*(C`$thingy\->can(\*(Aqsome_method\*(Aq)\ &&\ 1\*(C'\fR returns 1, which \f(CW\*(C`ok\*(C'\fR sees as
+a simple signal of success, as you would expect.
+.IP \(bu 4
+The syntax for \f(CW\*(C`skip\*(C'\fR is about the only way it can be, but it's still
+quite confusing. Just start with the above examples and you'll
+be okay.
+.Sp
+Moreover, users may expect this:
+.Sp
+.Vb 1
+\& skip $unless_mswin, foo($bar), baz($quux);
+.Ve
+.Sp
+to not evaluate \f(CWfoo($bar)\fR and \f(CWbaz($quux)\fR when the test is being
+skipped. But in reality, they \fIare\fR evaluated, but \f(CW\*(C`skip\*(C'\fR just won't
+bother comparing them if \f(CW$unless_mswin\fR is true.
+.Sp
+You could do this:
+.Sp
+.Vb 1
+\& skip $unless_mswin, sub{foo($bar)}, sub{baz($quux)};
+.Ve
+.Sp
+But that's not terribly pretty. You may find it simpler or clearer in
+the long run to just do things like this:
+.Sp
+.Vb 10
+\& if( $^O =~ m/MSWin/ ) {
+\& print "# Yay, we\*(Aqre under $^O\en";
+\& ok foo($bar), baz($quux);
+\& ok thing($whatever), baz($stuff);
+\& ok blorp($quux, $whatever);
+\& ok foo($barzbarz), thang($quux);
+\& } else {
+\& print "# Feh, we\*(Aqre under $^O. Watch me skip some tests...\en";
+\& for(1 .. 4) { skip "Skip unless under MSWin" }
+\& }
+.Ve
+.Sp
+But be quite sure that \f(CW\*(C`ok\*(C'\fR is called exactly as many times in the
+first block as \f(CW\*(C`skip\*(C'\fR is called in the second block.
+.SH ENVIRONMENT
+.IX Header "ENVIRONMENT"
+If \f(CW\*(C`PERL_TEST_DIFF\*(C'\fR environment variable is set, it will be used as a
+command for comparing unexpected multiline results. If you have GNU
+diff installed, you might want to set \f(CW\*(C`PERL_TEST_DIFF\*(C'\fR to \f(CW\*(C`diff \-u\*(C'\fR.
+If you don't have a suitable program, you might install the
+\&\f(CW\*(C`Text::Diff\*(C'\fR module and then set \f(CW\*(C`PERL_TEST_DIFF\*(C'\fR to be \f(CW\*(C`perl
+\&\-MText::Diff \-e \*(Aqprint diff(@ARGV)\*(Aq\*(C'\fR. If \f(CW\*(C`PERL_TEST_DIFF\*(C'\fR isn't set
+but the \f(CW\*(C`Algorithm::Diff\*(C'\fR module is available, then it will be used
+to show the differences in multiline results.
+.SH NOTE
+.IX Header "NOTE"
+A past developer of this module once said that it was no longer being
+actively developed. However, rumors of its demise were greatly
+exaggerated. Feedback and suggestions are quite welcome.
+.PP
+Be aware that the main value of this module is its simplicity. Note
+that there are already more ambitious modules out there, such as
+Test::More and Test::Unit.
+.PP
+Some earlier versions of this module had docs with some confusing
+typos in the description of \f(CWskip(...)\fR.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+Test::Harness
+.PP
+Test::Simple, Test::More, Devel::Cover
+.PP
+Test::Builder for building your own testing library.
+.PP
+Test::Unit is an interesting XUnit-style testing library.
+.PP
+Test::Inline lets you embed tests in code.
+.SH AUTHOR
+.IX Header "AUTHOR"
+Copyright (c) 1998\-2000 Joshua Nathaniel Pritikin.
+.PP
+Copyright (c) 2001\-2002 Michael G. Schwern.
+.PP
+Copyright (c) 2002\-2004 Sean M. Burke.
+.PP
+Current maintainer: Jesse Vincent. <jesse@bestpractical.com>
+.PP
+This package is free software and is provided "as is" without express
+or implied warranty. It may be used, redistributed and/or modified
+under the same terms as Perl itself.