unittests: Simple unit testing support for C++

repository files, history, tags

... clone: https://code.nxg.name/nxg/unittests

2020 June 25

Simple unit testing support for C++

There are various simple unit test frameworks for C++, and a variety of complicated ones, too (I'm sure). The following works for me. It is, as are many similar frameworks, at least loosely inspired by the xUnit design.

The software is Copyright 2016-19, Norman Gray, and is available under the terms of the 2-clause BSD licence. It is therefore perfectly happy to disappear into your source tree.

If the macro ARDUINO is defined at compilation time, then the framework builds in a variant which is buildable for the Arduino. See below.

The code is available in a repository at code.nxg.name, with downloads there.

Usage

To use, create one or more test files such as test-foo.cpp:

#include "unittests.h"

void test_foo(void)
{
    /* stuff... */
    assert_*(xxx)
}

void test_bar(void)
{
    // ...any tests
}

int main(int argc, char** argv)
{
    Testcase funcs[] = {
        { "basic foo", test_foo, },
        { "extra bar", test_bar, },
    };
    int nfuncs = sizeof(funcs)/sizeof(funcs[0]);

    return run_test_cases("suite-name", funcs, nfuncs, argc, argv);
}

The principal exposed function run_test_cases has declaration:

int run_test_cases(const char* suite_name,
                   const Testcase* cases,
                   const size_t n,
                   int argc,
                   char* argv[]);

where the type Testcase is:

typedef struct {
    const char* name;
    void (*f)(void);
} Testcase;

and

If suite_name is passed as NULL, then the suite name is taken from the leading element of argv.

Other functions:

The assertions can be:

Build with:

% c++ -o test-foo.o -c test-foo.cpp
% c++ -o unittests.o -c unittests.cpp
% c++ -o test-foo test-foo.o unittests.o

Then run with:

% ./test-foo            # run all the tests
% ./test-foo foo        # run the tests which have 'foo' in their description
% ./test-foo -h         # show options

Arduino

If the macro ARDUINO is defined at compilation time, then the framework builds in a variant which is buildable for the Arduino (no exceptions, and reporting output to a serial port).

Invoke as something like:

Testcase funcs[] = {
    // as above..
};
int nfuncs = sizeof(funcs)/sizeof(funcs[0]);

const char* dummy_argv[] = { "test-hhc-arduino", "-v" };
size_t nargs = sizeof(dummy_argv)/sizeof(dummy_argv[0]);

return run_test_cases(NULL, funcs, nfuncs, nargs, dummy_argv);

You can also compile with (some suitable equivalent of) -DTestSerial=Serial1 to have chatter sent to a different serial port.

Release notes

Norman Gray
https://nxg.me.uk

Norman
2020 June 25