A small unit-test harness that catches leaks, hangs and out-of-memory bugs.
A test file is a program. Include this header first, then the .c files under test, then write tests and a main that runs them:
#include "test/test.h"
#include "log/log.c"
#include "mem/mem.c"
#include "str/str.c"
}
int main(int argc, char **argv) {
test_init(argc, argv);
}
const char * str_cstr(const Str *s)
NUL-terminated contents of s, for C APIs such as fopen and puts.
#define SV(lit)
View of a string literal, with its length computed at compile time.
void str_free(Str *s)
Free the buffer and reset s to the zero state.
bool str_append(Str *s, StrView v)
Append v.
Owned, growable byte string.
#define RUN(name)
Run a test unless arguments name others, then print [ OK ] or [FAIL].
#define TEST(name)
Define a test.
#define REQUIRE(cond)
Record a failure when cond is false, and return from the test.
#define TEST_REPORT()
Print the totals.
#define CHECK_EQ_STR(a, b)
CHECK that two C strings are equal.
- CHECK records a failure and carries on. REQUIRE records it and returns from the test, for when the rest of it would be meaningless.
- Every file included after this one has malloc, calloc, realloc and free redirected to counting wrappers. RUN fails a test that ends with more live allocations than it started with, so leaks fail on every platform.
- test_fail_alloc_after() makes allocation fail on demand, so out-of-memory paths can be tested deterministically.
- A test still running after TEST_TIMEOUT_S seconds is reported as [HANG] and fails the run.
- Pass test names as arguments to run only those tests.
- Results are coloured when stdout supports it, as log_color_enabled() decides. The harness needs the log module, and log needs mem and str.
Every test in tests/ is written this way, so they are the best place to see the harness and the library in use.
|
| #define | TEST_TIMEOUT_S 10 |
| | Seconds before a running test counts as hung.
|
| #define | TEST(name) |
| | Define a test.
|
| #define | CHECK(cond) |
| | Record a failure when cond is false, and carry on.
|
| #define | REQUIRE(cond) |
| | Record a failure when cond is false, and return from the test.
|
| #define | CHECK_EQ_INT(a, b) |
| | CHECK that two integers are equal, printing both values when not.
|
| #define | CHECK_EQ_STR(a, b) |
| | CHECK that two C strings are equal.
|
| #define | CHECK_EQ_MEM(a, alen, b, blen) |
| | CHECK that two byte ranges have the same length and bytes, embedded NULs included.
|
| #define | RUN(name) |
| | Run a test unless arguments name others, then print [ OK ] or [FAIL].
|
| #define | TEST_REPORT() |
| | Print the totals.
|