vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

tap.3

(9855B)


      1 .Dd December 20, 2004
      2 .Os
      3 .Dt TAP 3
      4 .Sh NAME
      5 .Nm tap
      6 .Nd write tests that implement the Test Anything Protocol
      7 .Sh SYNOPSIS
      8 .In tap.h
      9 .Sh DESCRIPTION
     10 The
     11 .Nm
     12 library provides functions for writing test scripts that produce output
     13 consistent with the Test Anything Protocol.  A test harness that parses
     14 this protocol can run these tests and produce useful reports indicating
     15 their success or failure.
     16 .Ss PRINTF STRINGS
     17 In the descriptions that follow, for any function that takes as the
     18 last two parameters
     19 .Dq Fa const char * , Fa ...
     20 it can be assumed that the
     21 .Fa const char *
     22 is a
     23 .Fn printf
     24 -like format string, and the optional arguments are values to be placed
     25 in that string.
     26 .Ss TEST PLANS
     27 .Bl -tag -width indent
     28 .It Xo
     29 .Ft void
     30 .Fn plan_tests "unsigned int"
     31 .Xc
     32 .It Xo
     33 .Ft void
     34 .Fn plan_no_plan "void"
     35 .Xc
     36 .It Xo
     37 .Ft void
     38 .Fn plan_skip_all "const char *" "..."
     39 .Xc
     40 .El
     41 .Pp
     42 You must first specify a test plan.  This indicates how many tests you
     43 intend to run, and allows the test harness to notice if any tests were
     44 missed, or if the test program exited prematurely.
     45 .Pp
     46 To do this, use
     47 .Fn plan_tests .
     48 The function will cause your program to exit prematurely if you specify
     49 0 tests.
     50 .Pp
     51 In some situations you may not know how many tests you will be running, or
     52 you are developing your test program, and do not want to update the
     53 .Fn plan_tests
     54 parameter every time you make a change.  For those situations use
     55 .Fn plan_no_plan .
     56 It indicates to the test harness that an indeterminate number
     57 of tests will be run.
     58 .Pp
     59 Both
     60 .Fn plan_tests
     61 and
     62 .Fn plan_no_plan
     63 will cause your test program to exit prematurely with a diagnostic
     64 message if they are called more than once.
     65 .Pp
     66 If your test program detects at run time that some required functionality
     67 is missing (for example, it relies on a database connection which is not
     68 present, or a particular configuration option that has not been included
     69 in the running kernel) use
     70 .Fn plan_skip_all ,
     71 passing as parameters a string to display indicating the reason for skipping
     72 the tests.
     73 .Ss SIMPLE TESTS
     74 .Bl -tag -width indent
     75 .It Xo
     76 .Ft unsigned int
     77 .Fn ok "expression" "const char *" "..."
     78 .Xc
     79 .It Xo
     80 .Ft unsigned int
     81 .Fn ok1 "expression"
     82 .Xc
     83 .It Xo
     84 .Ft unsigned int
     85 .Fn pass "const char *" "..."
     86 .Xc
     87 .It Xo
     88 .Ft unsigned int
     89 .Fn fail "const char *" "..."
     90 .Xc
     91 .El
     92 .Pp
     93 Tests are implemented as expressions checked by calls to the
     94 .Fn ok
     95 and
     96 .Fn ok1
     97 macros.  In both cases
     98 .Fa expression
     99 should evaluate to true if the test succeeded.
    100 .Pp
    101 .Fn ok
    102 allows you to specify a name, or comment, describing the test which will
    103 be included in the output.
    104 .Fn ok1
    105 is for those times when the expression to be tested is self
    106 explanatory and does not need an associated comment.  In those cases
    107 the test expression becomes the comment.
    108 .Pp
    109 These four calls are equivalent:
    110 .Bd -literal -offset indent
    111 int i = 5;
    112 
    113 ok(i == 5, "i equals 5");      /* Overly verbose */
    114 ok(i == 5, "i equals %d", i);  /* Just to demonstrate printf-like
    115                                   behaviour of the test name */
    116 ok(i == 5, "i == 5");          /* Needless repetition */
    117 ok1(i == 5);                   /* Just right */
    118 .Ed
    119 .Pp
    120 It is good practice to ensure that the test name describes the meaning
    121 behind the test rather than what you are testing.  Viz
    122 .Bd -literal -offset indent
    123 ok(db != NULL, "db is not NULL");            /* Not bad, but */
    124 ok(db != NULL, "Database conn. succeeded");  /* this is better */
    125 .Ed
    126 .Pp
    127 .Fn ok
    128 and
    129 .Fn ok1
    130 return 1 if the expression evaluated to true, and 0 if it evaluated to
    131 false.  This lets you chain calls from
    132 .Fn ok
    133 to
    134 .Fn diag
    135 to only produce diagnostic output if the test failed.  For example, this
    136 code will include diagnostic information about why the database connection
    137 failed, but only if the test failed.
    138 .Bd -literal -offset indent
    139 if (!ok(db != NULL, "Database conn. succeeded")) {
    140     diag("Database error code: %d", dberrno);
    141 }
    142 .Ed
    143 .Pp
    144 You also have
    145 .Fn pass
    146 and
    147 .Fn fail .
    148 From the Test::More documentation:
    149 .Bd -literal -offset indent
    150 Sometimes you just want to say that the tests have passed.
    151 Usually the case is you've got some complicated condition
    152 that is difficult to wedge into an ok().  In this case,
    153 you can simply use pass() (to declare the test ok) or fail
    154 (for not ok).
    155 
    156 Use these very, very, very sparingly.
    157 .Ed
    158 .Pp
    159 These are synonyms for ok(1, ...) and ok(0, ...).
    160 .Ss SKIPPING TESTS
    161 .Bl -tag -width indent
    162 .It Xo
    163 .Ft void
    164 .Fn skip "unsigned int" "const char *" "..."
    165 .Xc
    166 .It Xo
    167 .Fn skip_if "expression" "unsigned int" "const char *" "..."
    168 .Xc
    169 .El
    170 .Pp
    171 Sets of tests can be skipped.  Ordinarily you would do this because
    172 the test can't be run in this particular testing environment.
    173 .Pp
    174 For example, suppose some tests should be run as root.  If the test is
    175 not being run as root then the tests should be skipped.  In this 
    176 implementation, skipped tests are flagged as being ok, with a special
    177 message indicating that they were skipped.  It is your responsibility
    178 to ensure that the number of tests skipped (the first parameter to
    179 .Fn skip )
    180 is correct for the number of tests to skip.
    181 .Pp
    182 One way of implementing this is with a
    183 .Dq do { } while(0);
    184 loop, or an
    185 .Dq if( ) { } else { }
    186 construct, to ensure that there are no additional side effects from the
    187 skipped tests.
    188 .Bd -literal -offset indent
    189 if(getuid() != 0) {
    190         skip(1, "because test only works as root");
    191 } else {
    192         ok(do_something_as_root() == 0, "Did something as root");
    193 }
    194 .Ed
    195 .Pp
    196 A convenient macro is provided to assist with this.  The previous example could
    197 be re-written as follows.
    198 .Bd -literal -offset indent
    199 skip_if(getuid() != 0, 1, "because test only works as root") {
    200 	ok(do_something_as_root() == 0, "Did something as root");
    201 }
    202 .Ed
    203 .Ss MARKING TESTS AS Dq TODO
    204 .Bl -tag -width indent
    205 .It Xo
    206 .Ft void
    207 .Fn todo_start "const char *" "..."
    208 .Xc
    209 .It Xo
    210 .Ft void
    211 .Fn todo_end "void"
    212 .Xc
    213 .El
    214 .Pp
    215 Sets of tests can be flagged as being
    216 .Dq TODO .
    217 These are tests that you expect to fail, probably because you haven't
    218 fixed a bug, or finished a new feature yet.  These tests will still be
    219 run, but with additional output that indicates that they are expected
    220 to fail.  Should a test start to succeed unexpectedly, tools like
    221 .Xr prove 1
    222 will indicate this, and you can move the test out of the todo
    223 block.  This is much more useful than simply commenting out (or
    224 .Dq #ifdef 0 ... #endif )
    225 the tests.
    226 .Bd -literal -offset indent
    227 todo_start("dwim() not returning true yet");
    228 
    229 ok(dwim(), "Did what the user wanted");
    230 
    231 todo_end();
    232 .Ed
    233 .Pp
    234 Should
    235 .Fn dwim
    236 ever start succeeding you will know about it as soon as you run the
    237 tests.  Note that
    238 .Em unlike
    239 the
    240 .Fn skip_*
    241 family, additional code between
    242 .Fn todo_start
    243 and
    244 .Fn todo_end
    245 .Em is
    246 executed.
    247 .Ss SKIP vs. TODO
    248 From the Test::More documentation;
    249 .Bd -literal -offset indent
    250 If it's something the user might not be able to do, use SKIP.
    251 This includes optional modules that aren't installed, running
    252 under an OS that doesn't have some feature (like fork() or
    253 symlinks), or maybe you need an Internet connection and one
    254 isn't available.
    255 
    256 If it's something the programmer hasn't done yet, use TODO.
    257 This is for any code you haven't written yet, or bugs you have
    258 yet to fix, but want to put tests in your testing script 
    259 (always a good idea).
    260 .Ed
    261 .Ss DIAGNOSTIC OUTPUT
    262 .Bl -tag -width indent
    263 .It Xo
    264 .Fr int
    265 .Fn diag "const char *" "..."
    266 .Xc
    267 .El
    268 .Pp
    269 If your tests need to produce diagnostic output, use
    270 .Fn diag .
    271 It ensures that the output will not be considered by the TAP test harness.
    272 .Fn diag
    273 adds the necessary trailing
    274 .Dq \en
    275 for you.
    276 It returns the number of characters written.
    277 .Bd -literal -offset indent
    278 diag("Expected return code 0, got return code %d", rcode);
    279 .Ed
    280 .Ss EXIT STATUS
    281 .Bl -tag -width indent
    282 .It Xo
    283 .Fr int
    284 .Fn exit_status void
    285 .Xc
    286 .El
    287 .Pp
    288 For maximum compatibility your test program should return a particular
    289 exit code.  This is calculated by
    290 .Fn exit_status
    291 so it is sufficient to always return from
    292 .Fn main
    293 with either
    294 .Dq return exit_status();
    295 or
    296 .Dq exit(exit_status());
    297 as appropriate.
    298 .Sh EXAMPLES
    299 The
    300 .Pa tests
    301 directory in the source distribution contains numerous tests of
    302 .Nm
    303 functionality, written using
    304 .Nm .
    305 Examine them for examples of how to construct test suites.
    306 .Sh COMPATIBILITY
    307 .Nm
    308 strives to be compatible with the Perl Test::More and Test::Harness 
    309 modules.  The test suite verifies that
    310 .Nm
    311 is bug-for-bug compatible with their behaviour.  This is why some
    312 functions which would more naturally return nothing return constant
    313 values.
    314 .Pp
    315 If the
    316 .Lb libpthread
    317 is found at compile time,
    318 .Nm
    319 .Em should
    320 be thread safe.  Indications to the contrary (and test cases that expose
    321 incorrect behaviour) are very welcome.
    322 .Sh SEE ALSO
    323 .Xr Test::More 1 ,
    324 .Xr Test::Harness 1 ,
    325 .Xr prove 1
    326 .Sh STANDARDS
    327 .Nm
    328 requires a
    329 .St -isoC-99
    330 compiler.  Some of the
    331 .Nm
    332 functionality is implemented as variadic macros, and that functionality
    333 was not formally codified until C99.  Patches to use
    334 .Nm
    335 with earlier compilers that have their own implementation of variadic
    336 macros will be gratefully received.
    337 .Sh HISTORY
    338 .Nm
    339 was written to help improve the quality and coverage of the FreeBSD
    340 regression test suite, and released in the hope that others find it
    341 a useful tool to help improve the quality of their code.
    342 .Sh AUTHORS
    343 .An "Nik Clayton" Aq nik@ngo.org.uk ,
    344 .Aq nik@FreeBSD.org
    345 .Pp
    346 .Nm
    347 would not exist without the efforts of
    348 .An "Michael G Schwern" Aq schqern@pobox.com ,
    349 .An "Andy Lester" Aq andy@petdance.com ,
    350 and the countless others who have worked on the Perl QA programme.
    351 .Sh BUGS
    352 Ideally, running the tests would have no side effects on the behaviour
    353 of the application you are testing.  However, it is not always possible
    354 to avoid them.  The following side effects of using
    355 .Nm
    356 are known.
    357 .Bl -bullet -offset indent
    358 .It
    359 stdout is set to unbuffered mode after calling any of the
    360 .Fn plan_*
    361 functions.
    362 .El