Boothj5

Full time software developer, part time hacker

Head-Unit

Head-Unit is a small unit testing framework for C and C++, written in C.

Installing head-unit

In the project folder, run:

make install

This will install head-unit in ~/lib and ~/include.

Alternatively you can download and install the debian binary package from here by running:

sudo dpkg -i libheadunit_0.11-1_amd64.deb

Using head-unit

Basic steps are:

  1. Write the tests
  2. Register the tests in a test module
  3. Register the test modules in a testsuite
  4. Run the testsuite

Write a test module

some-tests.c:

#include <string.h>
#include <head-unit.h>

static void setup(void)
{
    // ... do some setup for all tests ...
}

static void teardown(void)
{
    // ... close resources etc ...
}

static void beforetest(void)
{
    // ... code to run before each test ...
}

static void aftertest(void)
{
    // ... code to run after each test ...
}

static void test_something(void)
{
    // ... some code ...

    assert_true(somthing == 10);
}

static void test_something_else(void)
{
    // ... some code ...

    assert_true(strlen(something_else) > 10);
}

void register_some_tests()
{
    TEST_MODULE("some_tests");
    SETUP(setup);
    BEFORETEST(beforetest);
    AFTERTEST(aftertest);
    TEST(test_something);
    TEST(test_something_else);
    TEARDOWN(teardown);
}

The use of static is optional but stops tests with similar names in different source files conflicting.

The register function must not be static.

The SETUP, BEFORETEST, AFTERTEST and TEARDOWN functions and equivalent macros are optional.

Create the testsuite header and source file

testsuite.h:

#ifndef TESTSUITE_H
#define TESTSUITE_H

void register_some_tests(void) ;
void register_some_other_tests(void) ;

#endif

testsuite.c:

#include <head-unit.h>
#include "testsuite.h"

int main(void)
{
    register_some_tests() ;
    register_some_other_tests() ;
    run_suite() ;
    return 0 ;
}

Build and run the tests

C compiler flags:

-lstdc++ -I ~/include -L ~/lib -l headunit

C++ compiler flags:

-Wno-write-strings -I ~/include -L ~/lib -l headunit

Example C make targets:

compile-tests: testsuite.o some_tests.o something.o
$(CC) -lstdc++ testsuite.o some_tests.o something.o -I ~/include -L ~/lib -o testsuite -l headunit

test: compile-tests
    ./testsuite

Example C++ make targets:

compile-tests: testsuite.o some_tests.o something.o
$(CC) -Wno-write-strings testsuite.o some_tests.o something.o -I ~/include -L ~/lib -o testsuite -l headunit

test: compile-tests
    ./testsuite

C asserts

assert_true(int expression);
assert_false(int expression);
assert_int_equals(int expected, int actual);
assert_string_equals(char *expected, char *actual);
assert_is_null(void *ptr);

C++ asserts

assert_equals(T expected, T actual);

Where T must implement the following:

bool T::operator==(const T& other) const;
bool T::operator!=(const T& other) const;
ostream& operator<<(ostream& strm, const T& obj);

Source

The source can be found on Github