MULE 0.0.1
Multi-Use Library Essentials
Loading...
Searching...
No Matches
Test

Overview

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"
TEST(appends) {
Str s = { 0 };
REQUIRE(str_append(&s, SV("mule")));
CHECK_EQ_STR(str_cstr(&s), "mule");
str_free(&s);
}
int main(int argc, char **argv) {
test_init(argc, argv);
RUN(appends);
return TEST_REPORT();
}
const char * str_cstr(const Str *s)
NUL-terminated contents of s, for C APIs such as fopen and puts.
Definition str.c:216
#define SV(lit)
View of a string literal, with its length computed at compile time.
Definition str.h:80
void str_free(Str *s)
Free the buffer and reset s to the zero state.
Definition str.c:50
bool str_append(Str *s, StrView v)
Append v.
Definition str.c:89
Owned, growable byte string.
Definition str.h:64
#define RUN(name)
Run a test unless arguments name others, then print [ OK ] or [FAIL].
Definition test.h:288
#define TEST(name)
Define a test.
Definition test.h:206
#define REQUIRE(cond)
Record a failure when cond is false, and return from the test.
Definition test.h:212
#define TEST_REPORT()
Print the totals.
Definition test.h:309
#define CHECK_EQ_STR(a, b)
CHECK that two C strings are equal.
Definition test.h:224
  • 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.

Macros

#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.

Macro Definition Documentation

◆ TEST_TIMEOUT_S

#define TEST_TIMEOUT_S   10

Seconds before a running test counts as hung.

Define it before the include to change it.

Definition at line 60 of file test.h.

◆ TEST

#define TEST ( name)
Value:
static void name(void)

Define a test.

Run it from main with RUN.

Definition at line 206 of file test.h.

◆ CHECK

#define CHECK ( cond)
Value:
((void)test_check_((cond), __FILE__, __LINE__, #cond))

Record a failure when cond is false, and carry on.

Definition at line 209 of file test.h.

◆ REQUIRE

#define REQUIRE ( cond)
Value:
do { \
if (!test_check_((cond), __FILE__, __LINE__, #cond)) return; \
} while (0)

Record a failure when cond is false, and return from the test.

Definition at line 212 of file test.h.

◆ CHECK_EQ_INT

#define CHECK_EQ_INT ( a,
b )
Value:
((void)test_eq_int_((long long)(a), (long long)(b), __FILE__, __LINE__, \
#a, #b))

CHECK that two integers are equal, printing both values when not.

Definition at line 218 of file test.h.

◆ CHECK_EQ_STR

#define CHECK_EQ_STR ( a,
b )
Value:
((void)test_eq_str_((a), (b), __FILE__, __LINE__, #a, #b))

CHECK that two C strings are equal.

Two nulls are equal, a null and a string are not.

Definition at line 224 of file test.h.

◆ CHECK_EQ_MEM

#define CHECK_EQ_MEM ( a,
alen,
b,
blen )
Value:
((void)test_eq_mem_((a), (alen), (b), (blen), __FILE__, __LINE__, #a, #b))

CHECK that two byte ranges have the same length and bytes, embedded NULs included.

Definition at line 229 of file test.h.

◆ RUN

#define RUN ( name)
Value:
do { \
if (!test_selected_(#name)) break; \
long live_before_ = test_live_allocs_; \
test_cur_failed_ = 0; \
test_running_ = #name; \
alarm(TEST_TIMEOUT_S); \
name(); \
alarm(0); \
test_alloc_budget_ = -1; \
if (test_live_allocs_ != live_before_) { \
test_cur_failed_ = 1; \
printf(" %ld allocation(s) leaked\n", \
test_live_allocs_ - live_before_); \
} \
if (test_cur_failed_) test_failures_++; \
test_print_result_(#name); \
fflush(stdout); \
} while (0)
#define TEST_TIMEOUT_S
Seconds before a running test counts as hung.
Definition test.h:60

Run a test unless arguments name others, then print [ OK ] or [FAIL].

A leak or a hang fails the test too.

Definition at line 288 of file test.h.

◆ TEST_REPORT

#define TEST_REPORT ( )
Value:
test_report_(__FILE__)

Print the totals.

Return it from main: it is nonzero when a test failed.

Definition at line 309 of file test.h.