C unit tests with a small header-only library.

C unit tests

Minimalistic unit tests in C. Uses the __attribute__((constructor)) which, as far as I know, is supported by GCC and clang. So this probably only works for those compilers.

Example

To see the unit tests run:

$ git clone [email protected]:rubenvannieuwpoort/c_unit_tests.git
$ cd c_unit_tests
$ make test

Usage

Make a separate C source file for your tests that includes test.h. This file should not contain a main -- it is provided by the test.h header file. A unit test now looks like this:

UNIT_TEST(test_name) {
	// do something useful here
	test_assert(...);
}

This file can be compiled and run as usual. When running, it displays something like

test_name... SUCCESS
1 tests passed, 0 tests failed

And the program will exit with code 0 if all tests passed and 1 if there are failing tests.

I like to make a target test in the Makefile that runs the test binary, so that you can do make test to run the tests. See this repo for example:

$ make test
gcc testsuite.c -ggdb -O3 -o testsuite
./testsuite
hello... SUCCESS
goodbye... SUCCESS
loopy... SUCCESS
3 tests passed, 0 tests failed

How does it work?

Short story, it uses some macro magic.

Long story: UNIT_TEST is a macro. If you write UNIT_TEST(my_test), this line expands to

static void my_test(void);

static void __attribute__((constructor)) __construct_my_test(void) {
	add_test(my_test);
}

static void __real_my_test(void);

static void my_test(void) {
	printf("%s... ", __func__);
	fflush(stdout);
	__real_my_test();
}

static void __real_my_test(void)

Note that there is intentionally no semicolon on the last line: UNIT_TEST(my_test) should be followed by a block that makes up the body of the test. This code:

  1. Declares my_test but doesn't define it (a so-called forward declaration). This is necessary so that in the next step, we can use my_test without having defined it.
  2. Defines a __construct_my_test function. This has the __attribute__((constructor)) attribute, which means the function is executed even before main is executed (this is GCC-specific, see this page for more information). This code then runs add_test(my_test), which adds a function pointer to my_test to a global linked list (defined in test.h).
  3. We have another forward declaration, now for __real_my_test, the function that will contain the actual unit test code.
  4. It then defines a function my_test which prints my_test... and then runs __real_my_test.
  5. __real_my_test now contains the code block that was placed after UNIT_TEST(my_test) as its body.

The main method provided by test.h traverses the linked list with function pointers that was initialized by the __construct_my_test method (and other such methods if you have more testcases), and runs the functions in the linked list.

Then, the __real_my_test function is the actual tests which calls test_assert(condition), which, again, is a macro. It expands to:

do {
	if (condition) {
		printf("SUCCESS\n");
		tests_passed++;
	}
	else {
		printf("FAILED\n");
		tests_failed++;
	}
} while(0)

This do ... while is there to make sure the behavior is right when the macro is used in any context (see this page for a more in-depth explanation). The other code is straightforward. It prints SUCCESS or FAILED (which comes after the mytest... which was printed in my_test, assuming that no other stuff is printed before test_assert is called) and keeps track of the number of passed and failed tests.

Before terminating, main prints the number of tests passed and failed (or No tests are found if no tests have run at all).

Similar Resources

📝 One of the difficult unit tester for ft_containers project

📝 One of the difficult unit tester for ft_containers project

ft_containers-unit-test About ft containers unit test is a complete testing for project of school 21/ecole 42 and allowing you test your containers: V

Oct 1, 2022

Various Framework to do Unit Test in C++

Various Framework to do Unit Test in C++

Unit Test in C++ There are many frameworks to performs unit test in C++, we will present the most popular ones and show how to use them. The testing f

Nov 18, 2021

Kernel-mode C++ unit testing framework in BDD-style

There is a lack of unit testing frameworks that work in OS kernel. This library closes that gap and is targeted for windows driver developers.

Jun 11, 2022

Header-only C++11 library for property-based testing.

autocheck Header-only C++11 library for QuickCheck (and later, SmallCheck) testing. Please consult the wiki for documentation. Install conan remote ad

Apr 18, 2022

Header only C++14 mocking framework

Header only C++14 mocking framework

Trompeloeil Get: trompe l'oeil noun (Concise Encyclopedia) Style of representation in which a painted object is intended to deceive the viewer into be

Sep 23, 2022

C++ mocking made easy. A simple yet very expressive, headers only library for c++ mocking.

FakeIt GCC: MSC: FakeIt is a simple mocking framework for C++. It supports GCC, Clang and MS Visual C++. FakeIt is written in C++11 and can be used fo

Sep 28, 2022

The fastest feature-rich C++11/14/17/20 single-header testing framework

The fastest feature-rich C++11/14/17/20 single-header testing framework

master branch Windows All dev branch Windows All doctest is a new C++ testing framework but is by far the fastest both in compile times (by orders of

Sep 26, 2022

Simple, fast, accurate single-header microbenchmarking functionality for C++11/14/17/20

ankerl::nanobench ankerl::nanobench is a platform independent microbenchmarking library for C++11/14/17/20. #includ

Sep 30, 2022

The fastest feature-rich C++11/14/17/20 single-header testing framework

The fastest feature-rich C++11/14/17/20 single-header testing framework

master branch dev branch doctest is a new C++ testing framework but is by far the fastest both in compile times (by orders of magnitude) and runtime c

Sep 29, 2022
Comments
  • Remove malloc dependency

    Remove malloc dependency

    Hi,

    Thank you for the nice test suite. I am just wondering is there a particular reason you keep malloc dependency in add_test function? I followed the advise from lobste.rs and it look like that it works see my fork.

Related tags
A modern, C++11-native, single-file header-only, tiny framework for unit-tests, TDD and BDD (includes C++98 variant)

lest – lest errors escape testing This tiny C++11 test framework is based on ideas and examples by Kevlin Henney [1,2] and on ideas found in the CATCH

Sep 19, 2022
C++ Unit Testing Easier: A Header-only C++ unit testing framework

CUTE C++ Unit Testing Easier: A Header-only C++ unit testing framework usually available as part of the Cevelop C++ IDE (http://cevelop.com) Dependenc

Aug 31, 2022
The C Unit Testing Library on GitHub is a library designed for easy unit testing in C

The C Unit Testing Library on GitHub is a library designed for easy unit testing in C. It was written by Brennan Hurst for the purpose of providing a J-Unit-like testing framework within C for personal projects.

Oct 11, 2021
A complete unit testing framework in a header

liblittletest A complete unit testing framework in a header liblittletest is an easy to use all-in-an-header testing framework; all you have to do in

Nov 11, 2021
Upp11 - C++11 lightweight single header unit test framework

upp11 Lightweight C++11 single header unit test framework To use framework: Copy upp11.h in you project dir. Create unit test source files or modify e

Apr 4, 2019
Harbour DB speed tests comparison

hbDBSpeedTests Harbour DB speed tests comparison - Registers Count: 821051 MySql configuration( 1 or 2 ) /data/mysql/dbstru.zip - Import structure of

Nov 18, 2021
A micro unit-testing library for C/C++

µ-test A micro unit testing framework for C/C++ to get you up and running with unit-testing ASAP (even without libc). Usage Simply include the C and h

Dec 8, 2021
A dynamic mock tool for C/C++ unit test on Linux&MacOS X86_64

lmock 接口 替换一个函数,修改机器指令,用新函数替换旧函数,支持全局函数(包括第三方和系统函数)、成员函数(包括静态和虚函数)

Sep 20, 2022
UT: C++20 μ(micro)/Unit Testing Framework
UT: C++20 μ(micro)/Unit Testing Framework

"If you liked it then you "should have put a"_test on it", Beyonce rule UT / μt | Motivation | Quick Start | Overview | Tutorial | Examples | User Gui

Sep 28, 2022
Modern c++17 unit testing framework on Microsoft Windows, Apple macOS, Linux, iOS and android.
Modern c++17 unit testing framework on Microsoft Windows, Apple macOS, Linux, iOS and android.

tunit Modern c++17 unit testing framework on Windows, macOS, Linux, iOS and android. Continuous Integration build status Operating system Status Windo

Apr 5, 2022