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