What is the Best Unit Testing Framework in C for You?


You want to start Unit Testing in C and you want to use an existing Framework for this task. But how can you know which of all these Frameworks is the one that fits your need the best?

There are four well known Unit Test Frameworks for C where CppUTest is the best for projects that use pure C code. It is portable, lightweight and supports a Mocking Framework with CppUMock which can also handle C code.

If you don’t rely on mocking that much, rather mock manually or don’t like to use a C++ Framework for pure C code then your choice may differ. Let’s examine the four well known Unit Test Frameworks that you can use for testing your C code and find out which one is the best one for you.

The Best Unit Testing Framework in C for You

When you want to Unit Test in C you have to consider various things before you choose a Unit Test Framework. Because of the nature of C and C++ the most famous frameworks are all portable. With C you often want to have a lightweight framework to keep things clean and fast, especially when program in the embedded environment.

Test Doubles, in particular Mocks and Stubs are also a big part of testing. Some Frameworks support Mocking Frameworks, but sometimes not for C code. If you don’t use mocks or just as little that you write yours manually then you don’t attach too much importance to this criterion.

If you use a C++ Unit Test Framework would have to write C++ for your tests in some case. This could distract you from your actual work on the C Code.

Below is an overview of the most popular unit test frameworks for C and C++ to compare different features:

FrameworkLanguageC++ Knowledge
Required
LightweightMocking Framework
Support
Portable
CUnitCNoYesNoYes
UnityCNoYesYes (CMock)Yes
CppUTestC++NoYesYes (CppUMock)Yes
GoogleTestC++YesNoYes (GMock,
but C++ only)
Yes
Comparison of Unit Test Frameworks for C

Other Considerations for Unit Testing in C

There is no doubt that Unit Testing well done enhances your code quality as well as the quality of the final software and gives you confidence about your code base. If you are still unsure about this, you should read my article about unit testing in C and why you should do it.

Please note that Test Driven Development (TDD) is not the same as Unit Testing. You can write Unit Tests after writing the production code (which you would never do if you used TDD). TDD is a method that uses Unit Tests. However, when using TDD you automatically ensure a higher Unit Test Coverage (the linked article explains why this could matter).

You usually want to separate your test code from the production code by using different projects respectively different executable files. In the following paragraphs we will examine each of the four frameworks a little bit to improve your knowledge enough for making a choice.

Overview of Unit Test Frameworks for C

CUnit

On the Homepage of CUnitOpens in a new tab. the framework is described as “[…] a lightweight system for writing, administering, and running unit tests in C. It provides C programmers a basic testing functionality with a flexible variety of user interfaces.”

You download the code, build the lib and link it to your test project while including the header. The Library has currently (at the time of writing) four interfaces that can run the tests and report the results:

  • Automated: Output to XML-File
  • Basic: Flexible Programming Interface
  • Console: Console Interface (ANSI C)
  • Curses: GUI (Unix)
CUnit Console Output
Example Output for CUnit Test Running and Results

Unity

Unity is a small and straightforward Unit Test Framework. It is written in pure C and therefore has no C++ overload. You can download it hereOpens in a new tab., build it with CMake (on windows) or make (on Unix/Linux) and include the headers in your test file.

On the one hand it is very simple and quick and on the other hand it has an expressive feature set with lots of assertions to use. You can also build new macros or use CMock for full mocking support.

make
compiling shapetest.c
Linking MyShape_Unity_tests
Running MyShape_Unity_tests
..
----------------------
2 Tests 0 Failures 0 Ignored
OK

CppUTest

CppUTest is, as the name suggests, a C++ Unit Test Framework. You can find the current version on the GitHub pageOpens in a new tab.. As with the other tools you have to download the code and build it for your platform. Then you can use the headers and the library.

CppUTest only uses a primitive subset of C++ which also makes it a good choice for testing embedded development. It has several macros which make it so that you can write tests without any C++ knowledge.

CppUTest has a per test memory leak detection report which you can turn on or off before running your tests. You also have Mock support with CppUMock with which you can even mock c functions.

make
compiling shapetest.cpp
Linking MyShape_Unity_tests
Running MyShape_Unity_tests
...
stdio/shapetest.cpp:34: TEST(shape, DrawRectangle)
   expected <4 0x2>
   but was  <3 0x1>

Errors (1 failures, 3 tests, 3 ran, 2 checks, 0 ignored, 0 filtered out, 1ms)

GoogleTest (aka GTest)

Like CppUTest, GoogleTest is written in C++ but unlike CppUTest, you have to write C++ Code when testing C code with it. It is possible to write Unit Tests for C-Code in GTest, a fact that I already wrote an article about.

You have to download the source code of Google TestOpens in a new tab. and build it for the platform that you intend to use. Then you have to include the necessary headers and link to the library files you built.

GTest has a rich feature set with Test Fixtures (classes) to group tests, many assertions, parameterized tests and user defined matchers. You can also use GMock as a mocking framework for auto generated mocks. But beware that this may not be possible for C code because it relies on class features, therefore you may mock your c code manually.

GoogleTest Runner Example
Example of Google Test Runner results with some passed and a failed Test.

If you are still unsure which framework is the best for you, you may download all of them and test them one by one. Often you’ll find that syntax or how things are handled play a great role in your decision process. Give it a try.

Marco Lieblang

Professional Programmer since 2003, passionate Programmer since the mid 90's. Developing in many languages from C/C++ to Java, C#, Python and some more. And I also may know a bit about Assembly Languages and Retro Systems.

Recent Posts