tap.c - lightweight TAP output generator for C/C++ test suites
tap.c is intended to make writing TAP-based tests in C/C++ as easy as possible. It consists of a single file that can be included directly in test programs. The resulting test programs can be used with test harnesses such as AutoMake and prove.
- void tap_plan(int count)
-
Generate TAP plan. If the number of tests is unknown, use
tap_done_testing
instead. - void tap_skip_all(const char *reason, ...)
-
Skip all tests.
#ifdef RUN_DEVELOPER_TESTS run_developer_tests(); #else tap_skip_all("set -DRUN_DEVELOPER_TESTS to run"); #endif
- void tap_done_testing(void)
-
Indicate the end of testing for tests without a plan. If the number of tests is known, use
tap_plan
instead. - int tap_finish(void)
-
Returns
0
if all tests were run successfully,1
otherwise. Additionally, a diagnostic message will be printed if the number of tests run does match the number of tests planned. Provided as a convenience for test programs that should return non-zero on failure. - void tap_todo(const char *reason)
-
Indicate that the following tests are expected to fail. Set to
NULL
to disable. Note: the string passed is used as a diagnostic message and should not be free'd without updatingtap_todo
.tap_todo("make 1 equal 2"); tap_ok(1 == 2, "1 == 2"); // counted as success tap_todo(NULL); tap_ok(1 == 2, "1 == 2"); // counted as failure
- void tap_skip(int count, const char *reason, ...)
-
Skip tests.
#ifdef BAZ tap_ok(foo(), NULL); tap_ok(bar(), NULL); #else tap_skip(2, "foo and bar require BAZ"); #endif
- void tap_bail(const char *reason, ...)
-
Indicate an unrecoverable error. It is up to the caller to actually exit the test.
- void tap_assert(int condition)
-
If
condition
is falsetap_bail
will be called with an appropriate error message and the test program will immediately exit. Useful for performing test setup. - void tap_diag(const char *message, ...)
-
Print a diagnostic message. Harnesses should suppress the message for tests marked with
tap_todo
. - void tap_note(const char *message, ...)
-
Like
tap_diag
except harnesses should hide the message unless run in verbose mode. Useful for debugging the test itself.
The following are implemented as macros that simply wrap the underlying functions in order to provide file name and line information for diagnostic messages following unsuccessful tests. The underlying functions have a leading underscore (_
) and take the current file name and line number as their first two arguments. For example, the following two are equivalent:
tap_ok(success, name);
_tap_ok(__FILE__, __LINE__, success, name);
By using underlying functions, users can create their own test functions (see EXAMPLES).
- int tap_ok(int success, char *name, ...)
-
Check test success.
- int tap_vok(int success, char *name, va_list ap)
-
Equivalent to
tap_ok
except ava_list
is used rather than a variable number of arguments. - int tap_is_str(const char *got, const char *expected, const char *name, ...)
-
Compare two strings with helpful diagnostic output.
NULL
safe. - int tap_is_int(int got, int expected, const char *name, ...)
-
Compare two integers with helpful diagnostic output.
- int tap_is_float(float got, float expected, float delta, const char *name, ...)
-
Compare two floats with helpful diagnostic output. Success requires that the difference between
got
andexpected
must be less thandelta
.
#include <stdlib.h>
#include <string.h>
#include "tap.c"
int main(int argc, char **argv) {
tap_plan(3);
#define IS(got, exp) { char *c = got; tap_is_str(got, exp, #got); free(c); }
IS(strndup("foo", 4), "foo");
IS(strndup("foo", 3), "foo");
IS(strndup("foo", 2), "fo");
#undef IS
return tap_finish();
}
#include <string.h>
#include "tap.c"
#define is_array_str(...) _is_array_str(__FILE__, __LINE__, __VA_ARGS__)
int _is_array_str(const char *file, int lineno,
const char **got, const char **expected, const char *name, ...) {
size_t pos = 0;
int success = 1;
va_list ap;
va_start(ap, name);
while(*got && *expected && strcmp(*got, *expected) == 0) {
pos++;
got++;
expected++;
}
if(*got || *expected) { success = 0; }
if(!_tap_vok(file, lineno, success, name, ap)) {
tap_diag(" Arrays began differing at:");
if(*got) {
tap_diag(" got[%zu] = '%s'", pos, *got);
} else {
tap_diag(" got[%zu] = Does not exist", pos);
}
if(*expected) {
tap_diag(" expected[%zu] = '%s'", pos, *expected);
} else {
tap_diag(" expected[%zu] = Does not exist", pos);
}
}
va_end(ap);
return success;
}
int main(int argc, char **argv) {
char *got[] = { "foo", "bar", "baz", NULL };
char *expected[] = { "foo", "bar", "baz", "quux", NULL };
tap_plan(2);
is_array_str(got, expected, "this will fail");
expected[3] = NULL;
is_array_str(got, expected, "this will succeed");
return tap_finish();
}
Copyright 2014-2015 Andrew Gregory <andrew.gregory.8@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Project URL: http://github.com/andrewgregory/tap.c
TAP Specification: http://testanything.org/
TAP Producers:
- Test::More
- http://www.eyrie.org/~eagle/software/c-tap-harness/
- https://github.com/f0rk/libtap
- https://github.com/kawamuray/ctap
- https://github.com/lpsantil/picotap
- https://github.com/willemt/cutest
- https://github.com/zorgnax/libtap
- https://github.com/Leont/libtap-- (C++)
TAP Consumers: