xref: /freebsd/contrib/pam-krb5/tests/README (revision bf6873c5786e333d679a7838d28812febf479a8a)
1*bf6873c5SCy Schubert                            Writing TAP Tests
2*bf6873c5SCy Schubert
3*bf6873c5SCy SchubertIntroduction
4*bf6873c5SCy Schubert
5*bf6873c5SCy Schubert    This is a guide for users of the C TAP Harness package or similar
6*bf6873c5SCy Schubert    TAP-based test harnesses explaining how to write tests.  If your
7*bf6873c5SCy Schubert    package uses C TAP Harness as the test suite driver, you may want to
8*bf6873c5SCy Schubert    copy this document to an appropriate file name in your test suite as
9*bf6873c5SCy Schubert    documentation for contributors.
10*bf6873c5SCy Schubert
11*bf6873c5SCy SchubertAbout TAP
12*bf6873c5SCy Schubert
13*bf6873c5SCy Schubert    TAP is the Test Anything Protocol, a protocol for communication
14*bf6873c5SCy Schubert    between test cases and a test harness.  This is the protocol used by
15*bf6873c5SCy Schubert    Perl for its internal test suite and for nearly all Perl modules,
16*bf6873c5SCy Schubert    since it's the format used by the build tools for Perl modules to run
17*bf6873c5SCy Schubert    tests and report their results.
18*bf6873c5SCy Schubert
19*bf6873c5SCy Schubert    A TAP-based test suite works with a somewhat different set of
20*bf6873c5SCy Schubert    assumptions than an xUnit test suite.  In TAP, each test case is a
21*bf6873c5SCy Schubert    separate program.  That program, when run, must produce output in the
22*bf6873c5SCy Schubert    following format:
23*bf6873c5SCy Schubert
24*bf6873c5SCy Schubert        1..4
25*bf6873c5SCy Schubert        ok 1 - the first test
26*bf6873c5SCy Schubert        ok 2
27*bf6873c5SCy Schubert        # a diagnostic, ignored by the harness
28*bf6873c5SCy Schubert        not ok 3 - a failing test
29*bf6873c5SCy Schubert        ok 4 # skip a skipped test
30*bf6873c5SCy Schubert
31*bf6873c5SCy Schubert    The output should all go to standard output.  The first line specifies
32*bf6873c5SCy Schubert    the number of tests to be run, and then each test produces output that
33*bf6873c5SCy Schubert    looks like either "ok <n>" or "not ok <n>" depending on whether the
34*bf6873c5SCy Schubert    test succeeded or failed.  Additional information about the test can
35*bf6873c5SCy Schubert    be provided after the "ok <n>" or "not ok <n>", but is optional.
36*bf6873c5SCy Schubert    Additional diagnostics and information can be provided in lines
37*bf6873c5SCy Schubert    beginning with a "#".
38*bf6873c5SCy Schubert
39*bf6873c5SCy Schubert    Processing directives are supported after the "ok <n>" or "not ok <n>"
40*bf6873c5SCy Schubert    and start with a "#".  The main one of interest is "# skip" which says
41*bf6873c5SCy Schubert    that the test was skipped rather than successful and optionally gives
42*bf6873c5SCy Schubert    the reason.  Also supported is "# todo", which normally annotates a
43*bf6873c5SCy Schubert    failing test and indicates that test is expected to fail, optionally
44*bf6873c5SCy Schubert    providing a reason for why.
45*bf6873c5SCy Schubert
46*bf6873c5SCy Schubert    There are three more special cases.  First, the initial line stating
47*bf6873c5SCy Schubert    the number of tests to run, called the plan, may appear at the end of
48*bf6873c5SCy Schubert    the output instead of the beginning.  This can be useful if the number
49*bf6873c5SCy Schubert    of tests to run is not known in advance.  Second, a plan in the form:
50*bf6873c5SCy Schubert
51*bf6873c5SCy Schubert        1..0 # skip entire test case skipped
52*bf6873c5SCy Schubert
53*bf6873c5SCy Schubert    can be given instead, which indicates that this entire test case has
54*bf6873c5SCy Schubert    been skipped (generally because it depends on facilities or optional
55*bf6873c5SCy Schubert    configuration which is not present).  Finally, if the test case
56*bf6873c5SCy Schubert    encounters a fatal error, it should print the text:
57*bf6873c5SCy Schubert
58*bf6873c5SCy Schubert        Bail out!
59*bf6873c5SCy Schubert
60*bf6873c5SCy Schubert    on standard output, optionally followed by an error message, and then
61*bf6873c5SCy Schubert    exit.  This tells the harness that the test aborted unexpectedly.
62*bf6873c5SCy Schubert
63*bf6873c5SCy Schubert    The exit status of a successful test case should always be 0.  The
64*bf6873c5SCy Schubert    harness will report the test as "dubious" if all the tests appeared to
65*bf6873c5SCy Schubert    succeed but it exited with a non-zero status.
66*bf6873c5SCy Schubert
67*bf6873c5SCy SchubertWriting TAP Tests
68*bf6873c5SCy Schubert
69*bf6873c5SCy Schubert  Environment
70*bf6873c5SCy Schubert
71*bf6873c5SCy Schubert    One of the special features of C TAP Harness is the environment that
72*bf6873c5SCy Schubert    it sets up for your test cases.  If your test program is called under
73*bf6873c5SCy Schubert    the runtests driver, the environment variables C_TAP_SOURCE and
74*bf6873c5SCy Schubert    C_TAP_BUILD will be set to the top of the test directory in the source
75*bf6873c5SCy Schubert    tree and the top of the build tree, respectively.  You can use those
76*bf6873c5SCy Schubert    environment variables to locate additional test data, programs and
77*bf6873c5SCy Schubert    libraries built as part of your software build, and other supporting
78*bf6873c5SCy Schubert    information needed by tests.
79*bf6873c5SCy Schubert
80*bf6873c5SCy Schubert    The C and shell TAP libraries support a test_file_path() function,
81*bf6873c5SCy Schubert    which looks for a file under the build tree and then under the source
82*bf6873c5SCy Schubert    tree, using the C_TAP_BUILD and C_TAP_SOURCE environment variables,
83*bf6873c5SCy Schubert    and return the full path to the file.  This can be used to locate
84*bf6873c5SCy Schubert    supporting data files.  They also support a test_tmpdir() function
85*bf6873c5SCy Schubert    that returns a directory that can be used for temporary files during
86*bf6873c5SCy Schubert    tests.
87*bf6873c5SCy Schubert
88*bf6873c5SCy Schubert  Perl
89*bf6873c5SCy Schubert
90*bf6873c5SCy Schubert    Since TAP is the native test framework for Perl, writing TAP tests in
91*bf6873c5SCy Schubert    Perl is very easy and extremely well-supported.  If you've never
92*bf6873c5SCy Schubert    written tests in Perl before, start by reading the documentation for
93*bf6873c5SCy Schubert    Test::Tutorial and Test::Simple, which walks you through the basics,
94*bf6873c5SCy Schubert    including the TAP output syntax.  Then, the best Perl module to use
95*bf6873c5SCy Schubert    for serious testing is Test::More, which provides a lot of additional
96*bf6873c5SCy Schubert    functions over Test::Simple including support for skipping tests,
97*bf6873c5SCy Schubert    bailing out, and not planning tests in advance.  See the documentation
98*bf6873c5SCy Schubert    of Test::More for all the details and lots of examples.
99*bf6873c5SCy Schubert
100*bf6873c5SCy Schubert    C TAP Harness can run Perl test scripts directly and interpret the
101*bf6873c5SCy Schubert    results correctly, and similarly the Perl Test::Harness module and
102*bf6873c5SCy Schubert    prove command can run TAP tests written in other languages using, for
103*bf6873c5SCy Schubert    example, the TAP library that comes with C TAP Harness.  You can, if
104*bf6873c5SCy Schubert    you wish, use the library that comes with C TAP Harness but use prove
105*bf6873c5SCy Schubert    instead of runtests for running the test suite.
106*bf6873c5SCy Schubert
107*bf6873c5SCy Schubert  C
108*bf6873c5SCy Schubert
109*bf6873c5SCy Schubert    C TAP Harness provides a basic TAP library that takes away most of the
110*bf6873c5SCy Schubert    pain of writing TAP test cases in C.  A C test case should start with
111*bf6873c5SCy Schubert    a call to plan(), passing in the number of tests to run.  Then, each
112*bf6873c5SCy Schubert    test should use is_int(), is_string(), is_double(), or is_hex() as
113*bf6873c5SCy Schubert    appropriate to compare expected and seen values, or ok() to do a
114*bf6873c5SCy Schubert    simpler boolean test.  The is_*() functions take expected and seen
115*bf6873c5SCy Schubert    values and then a printf-style format string explaining the test
116*bf6873c5SCy Schubert    (which may be NULL).  ok() takes a boolean and then the printf-style
117*bf6873c5SCy Schubert    string.
118*bf6873c5SCy Schubert
119*bf6873c5SCy Schubert    Here's a complete example test program that uses the C TAP library:
120*bf6873c5SCy Schubert
121*bf6873c5SCy Schubert        #include <stddef.h>
122*bf6873c5SCy Schubert        #include <tap/basic.h>
123*bf6873c5SCy Schubert
124*bf6873c5SCy Schubert        int
125*bf6873c5SCy Schubert        main(void)
126*bf6873c5SCy Schubert        {
127*bf6873c5SCy Schubert            plan(4);
128*bf6873c5SCy Schubert
129*bf6873c5SCy Schubert            ok(1, "the first test");
130*bf6873c5SCy Schubert            is_int(42, 42, NULL);
131*bf6873c5SCy Schubert            diag("a diagnostic, ignored by the harness");
132*bf6873c5SCy Schubert            ok(0, "a failing test");
133*bf6873c5SCy Schubert            skip("a skipped test");
134*bf6873c5SCy Schubert
135*bf6873c5SCy Schubert            return 0;
136*bf6873c5SCy Schubert        }
137*bf6873c5SCy Schubert
138*bf6873c5SCy Schubert    This test program produces the output shown above in the section on
139*bf6873c5SCy Schubert    TAP and demonstrates most of the functions.  The other functions of
140*bf6873c5SCy Schubert    interest are sysdiag() (like diag() but adds strerror() results),
141*bf6873c5SCy Schubert    bail() and sysbail() for fatal errors, skip_block() to skip a whole
142*bf6873c5SCy Schubert    block of tests, and skip_all() which is called instead of plan() to
143*bf6873c5SCy Schubert    skip an entire test case.
144*bf6873c5SCy Schubert
145*bf6873c5SCy Schubert    The C TAP library also provides plan_lazy(), which can be called
146*bf6873c5SCy Schubert    instead of plan().  If plan_lazy() is called, the library will keep
147*bf6873c5SCy Schubert    track of how many test results are reported and will print out the
148*bf6873c5SCy Schubert    plan at the end of execution of the program.  This should normally be
149*bf6873c5SCy Schubert    avoided since the test may appear to be successful even if it exits
150*bf6873c5SCy Schubert    prematurely, but it can make writing tests easier in some
151*bf6873c5SCy Schubert    circumstances.
152*bf6873c5SCy Schubert
153*bf6873c5SCy Schubert    Complete API documentation for the basic C TAP library that comes with
154*bf6873c5SCy Schubert    C TAP Harness is available at:
155*bf6873c5SCy Schubert
156*bf6873c5SCy Schubert        <https://www.eyrie.org/~eagle/software/c-tap-harness/>
157*bf6873c5SCy Schubert
158*bf6873c5SCy Schubert    It's common to need additional test functions and utility functions
159*bf6873c5SCy Schubert    for your C tests, particularly if you have to set up and tear down a
160*bf6873c5SCy Schubert    test environment for your test programs, and it's useful to have them
161*bf6873c5SCy Schubert    all in the libtap library so that you only have to link your test
162*bf6873c5SCy Schubert    programs with one library.  Rather than editing tap/basic.c and
163*bf6873c5SCy Schubert    tap/basic.h to add those additional functions, add additional *.c and
164*bf6873c5SCy Schubert    *.h files into the tap directory with the function implementations and
165*bf6873c5SCy Schubert    prototypes, and then add those additional objects to the library.
166*bf6873c5SCy Schubert    That way, you can update tap/basic.c and tap/basic.h from subsequent
167*bf6873c5SCy Schubert    releases of C TAP Harness without having to merge changes with your
168*bf6873c5SCy Schubert    own code.
169*bf6873c5SCy Schubert
170*bf6873c5SCy Schubert    Libraries of additional useful TAP test functions are available in
171*bf6873c5SCy Schubert    rra-c-util at:
172*bf6873c5SCy Schubert
173*bf6873c5SCy Schubert        <https://www.eyrie.org/~eagle/software/rra-c-util/>
174*bf6873c5SCy Schubert
175*bf6873c5SCy Schubert    Some of the code there is particularly useful when testing programs
176*bf6873c5SCy Schubert    that require Kerberos keys.
177*bf6873c5SCy Schubert
178*bf6873c5SCy Schubert    If you implement new test functions that compare an expected and seen
179*bf6873c5SCy Schubert    value, it's best to name them is_<something> and take the expected
180*bf6873c5SCy Schubert    value, the seen value, and then a printf-style format string and
181*bf6873c5SCy Schubert    possible arguments to match the calling convention of the functions
182*bf6873c5SCy Schubert    provided by C TAP Harness.
183*bf6873c5SCy Schubert
184*bf6873c5SCy Schubert  Shell
185*bf6873c5SCy Schubert
186*bf6873c5SCy Schubert    C TAP Harness provides a library of shell functions to make it easier
187*bf6873c5SCy Schubert    to write TAP tests in shell.  That library includes much of the same
188*bf6873c5SCy Schubert    functionality as the C TAP library, but takes its parameters in a
189*bf6873c5SCy Schubert    somewhat different order to make better use of shell features.
190*bf6873c5SCy Schubert
191*bf6873c5SCy Schubert    The libtap.sh file should be installed in a directory named tap in
192*bf6873c5SCy Schubert    your test suite area.  It can then be loaded by tests written in shell
193*bf6873c5SCy Schubert    using the environment set up by runtests with:
194*bf6873c5SCy Schubert
195*bf6873c5SCy Schubert        . "$C_TAP_SOURCE"/tap/libtap.sh
196*bf6873c5SCy Schubert
197*bf6873c5SCy Schubert    Here is a complete test case written in shell which produces the same
198*bf6873c5SCy Schubert    output as the TAP sample above:
199*bf6873c5SCy Schubert
200*bf6873c5SCy Schubert        #!/bin/sh
201*bf6873c5SCy Schubert
202*bf6873c5SCy Schubert        . "$C_TAP_SOURCE"/tap/libtap.sh
203*bf6873c5SCy Schubert        cd "$C_TAP_BUILD"
204*bf6873c5SCy Schubert
205*bf6873c5SCy Schubert        plan 4
206*bf6873c5SCy Schubert        ok 'the first test' true
207*bf6873c5SCy Schubert        ok '' [ 42 -eq 42 ]
208*bf6873c5SCy Schubert        diag a diagnostic, ignored by the harness
209*bf6873c5SCy Schubert        ok '' false
210*bf6873c5SCy Schubert        skip 'a skipped test'
211*bf6873c5SCy Schubert
212*bf6873c5SCy Schubert    The shell framework doesn't provide the is_* functions, so you'll use
213*bf6873c5SCy Schubert    the ok function more.  It takes a string describing the text and then
214*bf6873c5SCy Schubert    treats all of its remaining arguments as a condition, evaluated the
215*bf6873c5SCy Schubert    same way as the arguments to the "if" statement.  If that condition
216*bf6873c5SCy Schubert    evaluates to true, the test passes; otherwise, the test fails.
217*bf6873c5SCy Schubert
218*bf6873c5SCy Schubert    The plan, plan_lazy, diag, and bail functions work the same as with
219*bf6873c5SCy Schubert    the C library.  skip takes a string and skips the next test with that
220*bf6873c5SCy Schubert    explanation.  skip_block takes a count and a string and skips that
221*bf6873c5SCy Schubert    many tests with that explanation.  skip_all takes an optional reason
222*bf6873c5SCy Schubert    and skips the entire test case.
223*bf6873c5SCy Schubert
224*bf6873c5SCy Schubert    Since it's common for shell programs to want to test the output of
225*bf6873c5SCy Schubert    commands, there's an additional function ok_program provided by the
226*bf6873c5SCy Schubert    shell test library.  It takes the test description string, the
227*bf6873c5SCy Schubert    expected exit status, the expected program output, and then treats the
228*bf6873c5SCy Schubert    rest of its arguments as the program to run.  That program is run with
229*bf6873c5SCy Schubert    standard error and standard output combined, and then its exit status
230*bf6873c5SCy Schubert    and output are tested against the provided values.
231*bf6873c5SCy Schubert
232*bf6873c5SCy Schubert    A utility function, strip_colon_error, is provided that runs the
233*bf6873c5SCy Schubert    command given as its arguments and strips text following a colon and a
234*bf6873c5SCy Schubert    space from the output (unless there is no whitespace on the line
235*bf6873c5SCy Schubert    before the colon and the space, normally indicating a prefix of the
236*bf6873c5SCy Schubert    program name).  This function can be used to wrap commands that are
237*bf6873c5SCy Schubert    expected to fail with output that has a system- or locale-specific
238*bf6873c5SCy Schubert    error message appended, such as the output of strerror().
239*bf6873c5SCy Schubert
240*bf6873c5SCy SchubertLicense
241*bf6873c5SCy Schubert
242*bf6873c5SCy Schubert    This file is part of the documentation of C TAP Harness, which can be
243*bf6873c5SCy Schubert    found at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
244*bf6873c5SCy Schubert
245*bf6873c5SCy Schubert    Copyright 2010, 2016 Russ Allbery <eagle@eyrie.org>
246*bf6873c5SCy Schubert
247*bf6873c5SCy Schubert    Copying and distribution of this file, with or without modification,
248*bf6873c5SCy Schubert    are permitted in any medium without royalty provided the copyright
249*bf6873c5SCy Schubert    notice and this notice are preserved.  This file is offered as-is,
250*bf6873c5SCy Schubert    without any warranty.
251*bf6873c5SCy Schubert
252*bf6873c5SCy Schubert    SPDX-License-Identifier: FSFAP
253