libtdd — a minimalist testing library for C
What is this?
libtdd is a minimalist testing framework inspired by the Golang `testing` package.
It is designed to provide a framework for scaffolding test suites during Test Driven Development (TDD).
This small C library attempts to provide a simple, feature-ful API for creating, running, and checking the results of tests. Simply declare test functions, add them to a suite in your `main()` function, compile and run.
Why does this exist?
This framework was written to assist in developing a genealogy library and application as a semester-long project for the so-called "Angel of Death" course (CIS*2750) during the second year of my undergrad program at the University of Guelph. The course required that we write entirely C99-compliant code, and (as is characteristic) project requirements ballooned in complexity as the semester wore on.
Absolutely terrified of introducing regressions when crashes could mean failing the course, I wrote this testing
framework so I could properly test my code within the restrictions of the course.
The framework uses a
pthread to execute each unit test on a background thread, which is monitored for
crashes with a SIGSEGV handler.
By modularlizing my library and application code, and writing test suites for every piece code, I was able to
test for edge cases and confidently perform sweeping refactors without fear of introducing regressions.
This approach ensured that I could be more relaxed during the course compared to some of my peers who working
without a testing framework.
Ultimately I received 100% overall in CIS*2750, and I have used this framework for every C-based course project since.
- Compliant with the POSIX C99 standard
- Compiles to a static or shared library
- Provides basic benchmarking with nano-second precision
- Catches and counts segmentation faults (crashes), which makes it easier to pinpoint unsafe memory access
- Collects and outputs statistics about test runs
- Allows organization of tests into labelled suites
- Fully documented with examples
- Single header-file public API
- Can be optionally compiled without colour output
- Parallel test execution
- Support for TAP and JSON output formats
- Improved benchmarking interface
- Support skipping tests
libtdd is built using the
To build and install the library along with its documentation, run the following commands.
meson setup --prefix=/usr/local _build ninja -C _build all docs install
This library requires
pthreads. You must link this library with your main test suite application.
Using this library should be intuitive to C programmers familiar with test driven development semantics.
suite_t is a set of a test runners. It is used to run a group of tests sequentially.
runner_t is a labelled handle to a test function.
A test function has the signature
void* test(void* t).
The void pointer will always be a
test_t*, but this signature is used to be compatible with the
Results of tests are recorded in
test_t structs using the following methods:
test_error(test_t* t, char* msg);Records an error condition.
test_fatal(test_t* t, char* msg);Immediately ends the current test, recording it as a failure.
test_timer_start(test_t*);Starts timing the execution of the test. This function is called automatically for benchmarking tests.
test_timer_end(test_t*);Ends the test execution timer. The function is called automatically for benchmarking tests.
An example program is included in the source repository.
Typically one will structure their project with src/ and test/ directories. The test directory should include a main program which includes headers from the src/ directory, and instantiates a test suite, registering a runner for each unit test.
Projects will benefit from multiple compilation targets with at least one for the test program.
The reporting interface currently looks something like the following.
This software is released under the ISC license. See the LICENSE file in the source repository for details.