[c] Unit Testing C Code

I worked on an embedded system this summer written in straight C. It was an existing project that the company I work for had taken over. I have become quite accustomed to writing unit tests in Java using JUnit but was at a loss as to the best way to write unit tests for existing code (which needed refactoring) as well as new code added to the system.

Are there any projects out there that make unit testing plain C code as easy as unit testing Java code with JUnit? Any insight that would apply specifically to embedded development (cross-compiling to arm-linux platform) would be greatly appreciated.

This question is related to c unit-testing testing embedded

The answer is


I'm surprised that no one mentioned Cutter (http://cutter.sourceforge.net/) You can test C and C++, it seamlessly integrates with autotools and has a really nice tutorial available.


If you're still on the hunt for test frameworks, CUnitWin32 is one for the Win32/NT platform.

This solves one fundamental problem that I faced with other testing frameworks. Namely global/static variables are in a deterministic state because each test is executed as a separate process.


I don't use a framework, I just use autotools "check" target support. Implement a "main" and use assert(s).

My test dir Makefile.am(s) look like:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp

API Sanity Checker — test framework for C/C++ libraries:

An automatic generator of basic unit tests for a shared C/C++ library. It is able to generate reasonable (in most, but unfortunately not all, cases) input data for parameters and compose simple ("sanity" or "shallow"-quality) test cases for every function in the API through the analysis of declarations in header files.

The quality of generated tests allows to check absence of critical errors in simple use cases. The tool is able to build and execute generated tests and detect crashes (segfaults), aborts, all kinds of emitted signals, non-zero program return code and program hanging.

Examples:


CppUTest - Highly recommended framework for unit testing C code.

The examples in the book that is mentioned in this thread TDD for embedded C are written using CppUTest.


In case you are targeting Win32 platforms or NT kernel mode, you should have a look at cfix.


After reading Minunit I thought a better way was base the test in assert macro which I use a lot like defensive program technique. So I used the same idea of Minunit mixed with standard assert. You can see my framework (a good name could be NoMinunit) in k0ga's blog


One technique to use is to develop the unit test code with a C++ xUnit framework (and C++ compiler), while maintaining the source for the target system as C modules.

Make sure you regularly compile your C source under your cross-compiler, automatically with your unit tests if possible.


I'm currently using the CuTest unit test framework:

http://cutest.sourceforge.net/

It's ideal for embedded systems as it's very lightweight and simple. I had no problems getting it to work on the target platform as well as on the desktop. In addition to writing the unit tests, all that's required is:

  • a header file included wherever you're calling the CuTest routines
  • a single additional 'C' file to be compiled/linked into the image
  • some simple code added to to main to set up and call the unit tests - I just have this in a special main() function that gets compiled if UNITTEST is defined during the build.

The system needs to support a heap and some stdio functionality (which not all embedded systems have). But the code is simple enough that you could probably work in alternatives to those requirements if your platform doesn't have them.

With some judicious use of extern "C"{} blocks it also supports testing C++ just fine.


I don't use a framework, I just use autotools "check" target support. Implement a "main" and use assert(s).

My test dir Makefile.am(s) look like:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp

First, look here: http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

My company has a C library our customers use. We use CxxTest (a C++ unit test library) to test the code. CppUnit will also work. If you're stuck in C, I'd recommend RCUNIT (but CUnit is good too).


I use CxxTest for an embedded c/c++ environment (primarily C++).

I prefer CxxTest because it has a perl/python script to build the test runner. After a small slope to get it setup (smaller still since you don't have to write the test runner), it's pretty easy to use (includes samples and useful documentation). The most work was setting up the 'hardware' the code accesses so I could unit/module test effectively. After that it's easy to add new unit test cases.

As mentioned previously it is a C/C++ unit test framework. So you will need a C++ compiler.

CxxTest User Guide CxxTest Wiki


There is CUnit

And Embedded Unit is unit testing framework for Embedded C System. Its design was copied from JUnit and CUnit and more, and then adapted somewhat for Embedded C System. Embedded Unit does not require std C libs. All objects are allocated to const area.

And Tessy automates the unit testing of embedded software.


As a C newbie, I found the slides called Test driven development in C very helpful. Basically, it uses the standard assert() together with && to deliver a message, without any external dependencies. If someone is used to a full stack testing framework, this probably won't do :)


First, look here: http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

My company has a C library our customers use. We use CxxTest (a C++ unit test library) to test the code. CppUnit will also work. If you're stuck in C, I'd recommend RCUNIT (but CUnit is good too).



We wrote CHEAT (hosted on GitHub) for easy usability and portability.

It has no dependencies and requires no installation or configuration. Only a header file and a test case is needed.

#include <cheat.h>

CHEAT_TEST(mathematics_still_work,
    cheat_assert(2 + 2 == 4);
    cheat_assert_not(2 + 2 == 5);
)

Tests compile into an executable that takes care of running the tests and reporting their outcomes.

$ gcc -I . tests.c
$ ./a.out
..
---
2 successful of 2 run
SUCCESS

It has pretty colors too.


CppUTest - Highly recommended framework for unit testing C code.

The examples in the book that is mentioned in this thread TDD for embedded C are written using CppUTest.


Google has excellent testing framework. https://github.com/google/googletest/blob/master/googletest/docs/primer.md

And yes, as far as I see it will work with plain C, i.e. doesn't require C++ features (may require C++ compiler, not sure).


First, look here: http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

My company has a C library our customers use. We use CxxTest (a C++ unit test library) to test the code. CppUnit will also work. If you're stuck in C, I'd recommend RCUNIT (but CUnit is good too).


Google has excellent testing framework. https://github.com/google/googletest/blob/master/googletest/docs/primer.md

And yes, as far as I see it will work with plain C, i.e. doesn't require C++ features (may require C++ compiler, not sure).



I'm currently using the CuTest unit test framework:

http://cutest.sourceforge.net/

It's ideal for embedded systems as it's very lightweight and simple. I had no problems getting it to work on the target platform as well as on the desktop. In addition to writing the unit tests, all that's required is:

  • a header file included wherever you're calling the CuTest routines
  • a single additional 'C' file to be compiled/linked into the image
  • some simple code added to to main to set up and call the unit tests - I just have this in a special main() function that gets compiled if UNITTEST is defined during the build.

The system needs to support a heap and some stdio functionality (which not all embedded systems have). But the code is simple enough that you could probably work in alternatives to those requirements if your platform doesn't have them.

With some judicious use of extern "C"{} blocks it also supports testing C++ just fine.


I just wrote Libcut out of frustration with existing C unit testing libraries. It has automatic type stringing of primitives (no need for test_eq_int, test_eq_long, test_eq_short, etc...; only two different sets for primitives and strings) and consists of one header file. Here's a short example:

#include <libcut.h>

LIBCUT_TEST(test_abc) {
    LIBCUT_TEST_EQ(1, 1);
    LIBCUT_TEST_NE(1, 0);
    LIBCUT_TEST_STREQ("abc", "abc");
    LIBCUT_TEST_STRNE("abc", "def");
}

LIBCUT_MAIN(test_abc);

It works only with C11, though.


I used RCUNIT to do some unit testing for embedded code on PC before testing on the target. Good hardware interface abstraction is important else endianness and memory mapped registers are going to kill you.


In case you are targeting Win32 platforms or NT kernel mode, you should have a look at cfix.


There is an elegant unit testing framework for C with support for mock objects called cmocka. It only requires the standard C library, works on a range of computing platforms (including embedded) and with different compilers.

It also has support for different message output formats like Subunit, Test Anything Protocol and jUnit XML reports.

cmocka has been created to also work on embedded platforms and also has Windows support.

A simple test looks like this:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
    (void) state; /* unused */
}

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(null_test_success),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

The API is fully documented and several examples are part of the source code.

To get started with cmocka you should read the article on LWN.net: Unit testing with mock objects in C

cmocka 1.0 has been released February 2015.


There is CUnit

And Embedded Unit is unit testing framework for Embedded C System. Its design was copied from JUnit and CUnit and more, and then adapted somewhat for Embedded C System. Embedded Unit does not require std C libs. All objects are allocated to const area.

And Tessy automates the unit testing of embedded software.


You also might want to take a look at libtap, a C testing framework which outputs the Test Anything Protocol (TAP) and thus integrates well with a variety of tools coming out for this technology. It's mostly used in the dynamic language world, but it's easy to use and becoming very popular.

An example:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}

I used RCUNIT to do some unit testing for embedded code on PC before testing on the target. Good hardware interface abstraction is important else endianness and memory mapped registers are going to kill you.


If you are familiar with JUnit then I recommend CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

That is assuming you have c++ compiler to do the unit tests. if not then I have to agree with Adam Rosenfield that check is what you want.


I'm currently using the CuTest unit test framework:

http://cutest.sourceforge.net/

It's ideal for embedded systems as it's very lightweight and simple. I had no problems getting it to work on the target platform as well as on the desktop. In addition to writing the unit tests, all that's required is:

  • a header file included wherever you're calling the CuTest routines
  • a single additional 'C' file to be compiled/linked into the image
  • some simple code added to to main to set up and call the unit tests - I just have this in a special main() function that gets compiled if UNITTEST is defined during the build.

The system needs to support a heap and some stdio functionality (which not all embedded systems have). But the code is simple enough that you could probably work in alternatives to those requirements if your platform doesn't have them.

With some judicious use of extern "C"{} blocks it also supports testing C++ just fine.


I'm surprised that no one mentioned Cutter (http://cutter.sourceforge.net/) You can test C and C++, it seamlessly integrates with autotools and has a really nice tutorial available.


You also might want to take a look at libtap, a C testing framework which outputs the Test Anything Protocol (TAP) and thus integrates well with a variety of tools coming out for this technology. It's mostly used in the dynamic language world, but it's easy to use and becoming very popular.

An example:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}


Google has excellent testing framework. https://github.com/google/googletest/blob/master/googletest/docs/primer.md

And yes, as far as I see it will work with plain C, i.e. doesn't require C++ features (may require C++ compiler, not sure).


LibU (http://koanlogic.com/libu) has an unit test module that allows explicit test suite/case dependencies, test isolation, parallel execution and a customizable report formatter (default formats are xml and txt).

The library is BSD licensed and contains many other useful modules - networking, debugging, commonly used data structures, configuration, etc. - should you need them in your projects ...


I use CxxTest for an embedded c/c++ environment (primarily C++).

I prefer CxxTest because it has a perl/python script to build the test runner. After a small slope to get it setup (smaller still since you don't have to write the test runner), it's pretty easy to use (includes samples and useful documentation). The most work was setting up the 'hardware' the code accesses so I could unit/module test effectively. After that it's easy to add new unit test cases.

As mentioned previously it is a C/C++ unit test framework. So you will need a C++ compiler.

CxxTest User Guide CxxTest Wiki


Google has excellent testing framework. https://github.com/google/googletest/blob/master/googletest/docs/primer.md

And yes, as far as I see it will work with plain C, i.e. doesn't require C++ features (may require C++ compiler, not sure).



If you're still on the hunt for test frameworks, CUnitWin32 is one for the Win32/NT platform.

This solves one fundamental problem that I faced with other testing frameworks. Namely global/static variables are in a deterministic state because each test is executed as a separate process.


After reading Minunit I thought a better way was base the test in assert macro which I use a lot like defensive program technique. So I used the same idea of Minunit mixed with standard assert. You can see my framework (a good name could be NoMinunit) in k0ga's blog


I didn't get far testing a legacy C application before I started looking for a way to mock functions. I needed mocks badly to isolate the C file I want to test from others. I gave cmock a try and I think I will adopt it.

Cmock scans header files and generates mock functions based on prototypes it finds. Mocks will allow you to test a C file in perfect isolation. All you will have to do is to link your test file with mocks instead of your real object files.

Another advantage of cmock is that it will validate parameters passed to mocked functions, and it will let you specify what return value the mocks should provide. This is very useful to test different flows of execution in your functions.

Tests consist of the typical testA(), testB() functions in which you build expectations, call functions to test and check asserts.

The last step is to generate a runner for your tests with unity. Cmock is tied to the unity test framework. Unity is as easy to learn as any other unit test framework.

Well worth a try and quite easy to grasp:

http://sourceforge.net/apps/trac/cmock/wiki

Update 1

Another framework I am investigating is Cmockery.

http://code.google.com/p/cmockery/

It is a pure C framework supporting unit testing and mocking. It has no dependency on ruby (contrary to Cmock) and it has very little dependency on external libs.

It requires a bit more manual work to setup mocks because it does no code generation. That does not represent a lot of work for an existing project since prototypes won't change much: once you have your mocks, you won't need to change them for a while (this is my case). Extra typing provides complete control of mocks. If there is something you don't like, you simply change your mock.

No need of a special test runner. You only need need to create an array of tests and pass it to a run_tests function. A bit more manual work here too but I definitely like the idea of a self-contained autonomous framework.

Plus it contains some nifty C tricks I didn't know.

Overall Cmockery needs a bit more understanding of mocks to get started. Examples should help you overcome this. It looks like it can do the job with simpler mechanics.


I used RCUNIT to do some unit testing for embedded code on PC before testing on the target. Good hardware interface abstraction is important else endianness and memory mapped registers are going to kill you.


One technique to use is to develop the unit test code with a C++ xUnit framework (and C++ compiler), while maintaining the source for the target system as C modules.

Make sure you regularly compile your C source under your cross-compiler, automatically with your unit tests if possible.


I just wrote Libcut out of frustration with existing C unit testing libraries. It has automatic type stringing of primitives (no need for test_eq_int, test_eq_long, test_eq_short, etc...; only two different sets for primitives and strings) and consists of one header file. Here's a short example:

#include <libcut.h>

LIBCUT_TEST(test_abc) {
    LIBCUT_TEST_EQ(1, 1);
    LIBCUT_TEST_NE(1, 0);
    LIBCUT_TEST_STREQ("abc", "abc");
    LIBCUT_TEST_STRNE("abc", "def");
}

LIBCUT_MAIN(test_abc);

It works only with C11, though.


I don't use a framework, I just use autotools "check" target support. Implement a "main" and use assert(s).

My test dir Makefile.am(s) look like:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp

I use CxxTest for an embedded c/c++ environment (primarily C++).

I prefer CxxTest because it has a perl/python script to build the test runner. After a small slope to get it setup (smaller still since you don't have to write the test runner), it's pretty easy to use (includes samples and useful documentation). The most work was setting up the 'hardware' the code accesses so I could unit/module test effectively. After that it's easy to add new unit test cases.

As mentioned previously it is a C/C++ unit test framework. So you will need a C++ compiler.

CxxTest User Guide CxxTest Wiki


Michael Feather's book "Working Effectively with Legacy Code" presents a lot of techniques specific to unit testing during C development.

There are techniques related to dependency injection that are specific to C which I haven't seen anywhere else.



Personally I like the Google Test framework.

The real difficulty in testing C code is breaking the dependencies on external modules so you can isolate code in units. This can be especially problematic when you are trying to get tests around legacy code. In this case I often find myself using the linker to use stubs functions in tests.

This is what people are referring to when they talk about "seams". In C your only option really is to use the pre-processor or the linker to mock out your dependencies.

A typical test suite in one of my C projects might look like this:

#include "myimplementationfile.c"
#include <gtest/gtest.h>

// Mock out external dependency on mylogger.o
void Logger_log(...){}

TEST(FactorialTest, Zero) {
    EXPECT_EQ(1, Factorial(0));
}

Note that you are actually including the C file and not the header file. This gives the advantage of access to all the static data members. Here I mock out my logger (which might be in logger.o and give an empty implementation. This means that the test file compiles and links independently from the rest of the code base and executes in isolation.

As for cross-compiling the code, for this to work you need good facilities on the target. I have done this with googletest cross compiled to Linux on a PowerPC architecture. This makes sense because there you have a full shell and os to gather your results. For less rich environments (which I classify as anything without a full OS) you should just build and run on the host. You should do this anyway so you can run the tests automatically as part of the build.

I find testing C++ code is generally much easier due to the fact that OO code is in general much less coupled than procedural (of course this depends a lot on coding style). Also in C++ you can use tricks like dependency injection and method overriding to get seams into code that is otherwise encapsulated.

Michael Feathers has an excellent book about testing legacy code. In one chapter he covers techniques for dealing with non-OO code which I highly recommend.

Edit: I've written a blog post about unit testing procedural code, with source available on GitHub.

Edit: There is a new book coming out from the Pragmatic Programmers that specifically addresses unit testing C code which I highly recommend.


Cmockery is a recently launched project that consists on a very simple to use C library for writing unit tests.


One technique to use is to develop the unit test code with a C++ xUnit framework (and C++ compiler), while maintaining the source for the target system as C modules.

Make sure you regularly compile your C source under your cross-compiler, automatically with your unit tests if possible.


other than my obvious bias

http://code.google.com/p/seatest/

is a nice simple way to unit test C code. mimics xUnit


I used RCUNIT to do some unit testing for embedded code on PC before testing on the target. Good hardware interface abstraction is important else endianness and memory mapped registers are going to kill you.


I say almost the same as ratkok but if you have a embedded twist to the unit tests then...

Unity - Highly recommended framework for unit testing C code.

#include <unity.h>

void test_true_should_be_true(void)
{
    TEST_ASSERT_TRUE(true);
}

int main(void)
{
    UNITY_BEGIN();
    RUN_TEST(test_true_should_be_true);
    return UNITY_END();
}

The examples in the book that is mentioned in this thread TDD for embedded C are written using Unity (and CppUTest).


In case you are targeting Win32 platforms or NT kernel mode, you should have a look at cfix.


I use CxxTest for an embedded c/c++ environment (primarily C++).

I prefer CxxTest because it has a perl/python script to build the test runner. After a small slope to get it setup (smaller still since you don't have to write the test runner), it's pretty easy to use (includes samples and useful documentation). The most work was setting up the 'hardware' the code accesses so I could unit/module test effectively. After that it's easy to add new unit test cases.

As mentioned previously it is a C/C++ unit test framework. So you will need a C++ compiler.

CxxTest User Guide CxxTest Wiki


If you are familiar with JUnit then I recommend CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

That is assuming you have c++ compiler to do the unit tests. if not then I have to agree with Adam Rosenfield that check is what you want.


I didn't get far testing a legacy C application before I started looking for a way to mock functions. I needed mocks badly to isolate the C file I want to test from others. I gave cmock a try and I think I will adopt it.

Cmock scans header files and generates mock functions based on prototypes it finds. Mocks will allow you to test a C file in perfect isolation. All you will have to do is to link your test file with mocks instead of your real object files.

Another advantage of cmock is that it will validate parameters passed to mocked functions, and it will let you specify what return value the mocks should provide. This is very useful to test different flows of execution in your functions.

Tests consist of the typical testA(), testB() functions in which you build expectations, call functions to test and check asserts.

The last step is to generate a runner for your tests with unity. Cmock is tied to the unity test framework. Unity is as easy to learn as any other unit test framework.

Well worth a try and quite easy to grasp:

http://sourceforge.net/apps/trac/cmock/wiki

Update 1

Another framework I am investigating is Cmockery.

http://code.google.com/p/cmockery/

It is a pure C framework supporting unit testing and mocking. It has no dependency on ruby (contrary to Cmock) and it has very little dependency on external libs.

It requires a bit more manual work to setup mocks because it does no code generation. That does not represent a lot of work for an existing project since prototypes won't change much: once you have your mocks, you won't need to change them for a while (this is my case). Extra typing provides complete control of mocks. If there is something you don't like, you simply change your mock.

No need of a special test runner. You only need need to create an array of tests and pass it to a run_tests function. A bit more manual work here too but I definitely like the idea of a self-contained autonomous framework.

Plus it contains some nifty C tricks I didn't know.

Overall Cmockery needs a bit more understanding of mocks to get started. Examples should help you overcome this. It looks like it can do the job with simpler mechanics.


Minunit is an incredibly simple unit testing framework. I'm using it to unit test c microcontroller code for avr.


I say almost the same as ratkok but if you have a embedded twist to the unit tests then...

Unity - Highly recommended framework for unit testing C code.

#include <unity.h>

void test_true_should_be_true(void)
{
    TEST_ASSERT_TRUE(true);
}

int main(void)
{
    UNITY_BEGIN();
    RUN_TEST(test_true_should_be_true);
    return UNITY_END();
}

The examples in the book that is mentioned in this thread TDD for embedded C are written using Unity (and CppUTest).


I don't use a framework, I just use autotools "check" target support. Implement a "main" and use assert(s).

My test dir Makefile.am(s) look like:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp

Cmockery is a recently launched project that consists on a very simple to use C library for writing unit tests.


other than my obvious bias

http://code.google.com/p/seatest/

is a nice simple way to unit test C code. mimics xUnit


There is CUnit

And Embedded Unit is unit testing framework for Embedded C System. Its design was copied from JUnit and CUnit and more, and then adapted somewhat for Embedded C System. Embedded Unit does not require std C libs. All objects are allocated to const area.

And Tessy automates the unit testing of embedded software.


LibU (http://koanlogic.com/libu) has an unit test module that allows explicit test suite/case dependencies, test isolation, parallel execution and a customizable report formatter (default formats are xml and txt).

The library is BSD licensed and contains many other useful modules - networking, debugging, commonly used data structures, configuration, etc. - should you need them in your projects ...


Minunit is an incredibly simple unit testing framework. I'm using it to unit test c microcontroller code for avr.


Personally I like the Google Test framework.

The real difficulty in testing C code is breaking the dependencies on external modules so you can isolate code in units. This can be especially problematic when you are trying to get tests around legacy code. In this case I often find myself using the linker to use stubs functions in tests.

This is what people are referring to when they talk about "seams". In C your only option really is to use the pre-processor or the linker to mock out your dependencies.

A typical test suite in one of my C projects might look like this:

#include "myimplementationfile.c"
#include <gtest/gtest.h>

// Mock out external dependency on mylogger.o
void Logger_log(...){}

TEST(FactorialTest, Zero) {
    EXPECT_EQ(1, Factorial(0));
}

Note that you are actually including the C file and not the header file. This gives the advantage of access to all the static data members. Here I mock out my logger (which might be in logger.o and give an empty implementation. This means that the test file compiles and links independently from the rest of the code base and executes in isolation.

As for cross-compiling the code, for this to work you need good facilities on the target. I have done this with googletest cross compiled to Linux on a PowerPC architecture. This makes sense because there you have a full shell and os to gather your results. For less rich environments (which I classify as anything without a full OS) you should just build and run on the host. You should do this anyway so you can run the tests automatically as part of the build.

I find testing C++ code is generally much easier due to the fact that OO code is in general much less coupled than procedural (of course this depends a lot on coding style). Also in C++ you can use tricks like dependency injection and method overriding to get seams into code that is otherwise encapsulated.

Michael Feathers has an excellent book about testing legacy code. In one chapter he covers techniques for dealing with non-OO code which I highly recommend.

Edit: I've written a blog post about unit testing procedural code, with source available on GitHub.

Edit: There is a new book coming out from the Pragmatic Programmers that specifically addresses unit testing C code which I highly recommend.


Cmockery is a recently launched project that consists on a very simple to use C library for writing unit tests.


Michael Feather's book "Working Effectively with Legacy Code" presents a lot of techniques specific to unit testing during C development.

There are techniques related to dependency injection that are specific to C which I haven't seen anywhere else.


As a C newbie, I found the slides called Test driven development in C very helpful. Basically, it uses the standard assert() together with && to deliver a message, without any external dependencies. If someone is used to a full stack testing framework, this probably won't do :)


If you're still on the hunt for test frameworks, CUnitWin32 is one for the Win32/NT platform.

This solves one fundamental problem that I faced with other testing frameworks. Namely global/static variables are in a deterministic state because each test is executed as a separate process.


API Sanity Checker — test framework for C/C++ libraries:

An automatic generator of basic unit tests for a shared C/C++ library. It is able to generate reasonable (in most, but unfortunately not all, cases) input data for parameters and compose simple ("sanity" or "shallow"-quality) test cases for every function in the API through the analysis of declarations in header files.

The quality of generated tests allows to check absence of critical errors in simple use cases. The tool is able to build and execute generated tests and detect crashes (segfaults), aborts, all kinds of emitted signals, non-zero program return code and program hanging.

Examples:


If you are familiar with JUnit then I recommend CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

That is assuming you have c++ compiler to do the unit tests. if not then I have to agree with Adam Rosenfield that check is what you want.


We wrote CHEAT (hosted on GitHub) for easy usability and portability.

It has no dependencies and requires no installation or configuration. Only a header file and a test case is needed.

#include <cheat.h>

CHEAT_TEST(mathematics_still_work,
    cheat_assert(2 + 2 == 4);
    cheat_assert_not(2 + 2 == 5);
)

Tests compile into an executable that takes care of running the tests and reporting their outcomes.

$ gcc -I . tests.c
$ ./a.out
..
---
2 successful of 2 run
SUCCESS

It has pretty colors too.


Minunit is an incredibly simple unit testing framework. I'm using it to unit test c microcontroller code for avr.


Cmockery is a recently launched project that consists on a very simple to use C library for writing unit tests.


If you're still on the hunt for test frameworks, CUnitWin32 is one for the Win32/NT platform.

This solves one fundamental problem that I faced with other testing frameworks. Namely global/static variables are in a deterministic state because each test is executed as a separate process.


You also might want to take a look at libtap, a C testing framework which outputs the Test Anything Protocol (TAP) and thus integrates well with a variety of tools coming out for this technology. It's mostly used in the dynamic language world, but it's easy to use and becoming very popular.

An example:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}

If you are familiar with JUnit then I recommend CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

That is assuming you have c++ compiler to do the unit tests. if not then I have to agree with Adam Rosenfield that check is what you want.


Minunit is an incredibly simple unit testing framework. I'm using it to unit test c microcontroller code for avr.


You also might want to take a look at libtap, a C testing framework which outputs the Test Anything Protocol (TAP) and thus integrates well with a variety of tools coming out for this technology. It's mostly used in the dynamic language world, but it's easy to use and becoming very popular.

An example:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}

There is CUnit

And Embedded Unit is unit testing framework for Embedded C System. Its design was copied from JUnit and CUnit and more, and then adapted somewhat for Embedded C System. Embedded Unit does not require std C libs. All objects are allocated to const area.

And Tessy automates the unit testing of embedded software.


There is an elegant unit testing framework for C with support for mock objects called cmocka. It only requires the standard C library, works on a range of computing platforms (including embedded) and with different compilers.

It also has support for different message output formats like Subunit, Test Anything Protocol and jUnit XML reports.

cmocka has been created to also work on embedded platforms and also has Windows support.

A simple test looks like this:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
    (void) state; /* unused */
}

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(null_test_success),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

The API is fully documented and several examples are part of the source code.

To get started with cmocka you should read the article on LWN.net: Unit testing with mock objects in C

cmocka 1.0 has been released February 2015.


First, look here: http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

My company has a C library our customers use. We use CxxTest (a C++ unit test library) to test the code. CppUnit will also work. If you're stuck in C, I'd recommend RCUNIT (but CUnit is good too).



One technique to use is to develop the unit test code with a C++ xUnit framework (and C++ compiler), while maintaining the source for the target system as C modules.

Make sure you regularly compile your C source under your cross-compiler, automatically with your unit tests if possible.


In case you are targeting Win32 platforms or NT kernel mode, you should have a look at cfix.


Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to unit-testing

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0 How to test the type of a thrown exception in Jest Unit Tests not discovered in Visual Studio 2017 Class Not Found: Empty Test Suite in IntelliJ Angular 2 Unit Tests: Cannot find name 'describe' Enzyme - How to access and set <input> value? Mocking HttpClient in unit tests Example of Mockito's argumentCaptor How to write unit testing for Angular / TypeScript for private methods with Jasmine Why is the Visual Studio 2015/2017/2019 Test Runner not discovering my xUnit v2 tests

Examples related to testing

Test process.env with Jest How to configure "Shorten command line" method for whole project in IntelliJ Jest spyOn function called Simulate a button click in Jest Mockito - NullpointerException when stubbing Method toBe(true) vs toBeTruthy() vs toBeTrue() How-to turn off all SSL checks for postman for a specific site What is the difference between smoke testing and sanity testing? ReferenceError: describe is not defined NodeJs How to properly assert that an exception gets raised in pytest?

Examples related to embedded

Compiling an application for use in highly radioactive environments Sorting 1 million 8-decimal-digit numbers with 1 MB of RAM What does this GCC error "... relocation truncated to fit..." mean? How do you implement a class in C? Understanding Linux /proc/id/maps Using floats with sprintf() in embedded C What is the difference between C and embedded C? Unit Testing C Code