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.
Features
- 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
Planned features
- Parallel test execution
- Support for TAP and JSON output formats
- Improved benchmarking interface
- Support skipping tests
Installation
libtdd
is built using the meson
build system.
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
Dependencies
This library requires pthread
s. You must link this library with your main test suite application.
Usage
Using this library should be intuitive to C programmers familiar with test driven development semantics.
Concepts
Test Suites.
A suite suite_t
is a set of a test runners. It is used to run a group of tests sequentially.
Test runners.
A test runner_t
is a labelled handle to a test function.
Test functions.
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
thread interface.
Test recorders.
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.
Example
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.
License
This software is released under the ISC license. See the LICENSE file in the source repository for details.