CUnit
CUnit is a testing framework for the C programming language. It's not a popular testing framework, nor it is commonly used. β οΈ
$ sudo apt-get update
$ sudo apt-get install libcunit1 libcunit1-doc libcunit1-dev
The documentation is available here.
Get Started with CMake
Assuming you want to use cunit
with a cmake project, you'll have to manually write some code first. Add to a CMakeLists.txt
:
find_package(CUnit REQUIRED)
You need to create a finder ./cmake/modules/FindCUnit.cmake
.
find_path(CUNIT_INCLUDE_DIRS CUnit/CUnit.h)
find_library(CUNIT_LIBRARIES NAMES CUnit cunit)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CUnit
REQUIRED_VARS CUNIT_INCLUDE_DIRS CUNIT_LIBRARIES
VERSION_VAR CUNIT_VERSION)
Add to a CMakeLists.txt
before the find_package
call:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
There is obviously no support for ctest
. We can only generate an executable and run it.
# Create an executable for your test suites
add_executable(my_testing_target
tests/runner.c
tests/my_suite.c
tests/my_suite.h
# ...
)
# Link CUnit to your test target
target_link_libraries(my_testing_target ${CUNIT_LIBRARIES})
Basic Test Suite
A suite is a group of tests that share the same purpose, e.g., for instance, tests that are specific to one component/function/file.
Let's first define a header my_suite.h
. It only exposes to others a way to create our suite, which is needed to run it.
#ifndef MY_SUITE_H
#define MY_SUITE_H
int my_suite_createSuite();
#endif //MY_SUITE_H
To create a suite, we need to use CU_add_suite
.
#include <CUnit/CUnit.h>
#include <stdlib.h>
int my_suite_createSuite() {
CU_pSuite suite = NULL;
// Add our suite to the registry
suite = CU_add_suite("Suite_Name", NULL, NULL);
if (NULL == suite) {
CU_cleanup_registry();
return CU_get_error();
}
// Add our test to the suite
// ...
return EXIT_SUCCESS;
}
β‘οΈ CU_add_suite
allows you to define two methods which are respectively called before and after all tests.
Now, we can start writing some tests:
#include <CUnit/CUnit.h>
void test_example(void) {
CU_ASSERT(1 == 1); // test passed if true
CU_ASSERT_TRUE(1); // test passed if true
CU_ASSERT_FALSE(0); // test passed if false
CU_ASSERT_PTR_NULL(NULL); // test passed if null
CU_ASSERT_PTR_NOT_NULL(NULL); // test pass if not null
CU_ASSERT_EQUAL(1, 1); // test passed if equal
CU_ASSERT_NOT_EQUAL(5, 0) // test passed if different
CU_ASSERT_STRING_EQUAL("x", "y") // test passed if equal
CU_ASSERT_STRING_NOT_EQUAL("x", "y") // test passed if different
CU_PASS("msg"); // mark the test as successful
CU_FAIL("msg"); // mark the test as failed
// see also: CU_ASSERT_PTR_EQUAL, *_FATAL, etc.
}
You will then have to add them to your suite:
// Add our test to the suite
if (NULL == CU_add_test(suite, "Test_Name", test_example)) {
return EXIT_FAILURE;
}
// ...
If needed, you can get the error message of a failed test using:
char* msg = CU_get_error_msg();
Running Tests
To run your tests, you will have to initialize CUnit, declare listSuite
, and pick a runner. First, to initialize CUnit:
#include <CUnit/CUnit.h>
#include <stdlib.h>
int main() {
CU_pSuite pSuite = NULL;
int res;
/* initialize the CUnit test registry */
if (CUE_SUCCESS != CU_initialize_registry())
return CU_get_error();
for (int i = 0; i < NUMBER_OF_SUITES; i++) {
res = listSuite[i](pSuite);
if (res == EXIT_FAILURE) {
CU_cleanup_registry();
return CU_get_error();
}
}
/* Run all tests using the ??? interface */
/* ... */
/* Clean up registry and return */
CU_cleanup_registry();
return CU_get_error();
}
The listSuite
array contains all of your suite initialization methods allowing us to connect them to the runner.
#include "my_suite.h"
// Add all methods to create suites below
#define NUMBER_OF_SUITES 1
int (*listSuite[NUMBER_OF_SUITES])(CU_pSuite) = {
my_suite_createSuite
};
Using the basic runner π, test results are printed on the screen.
#include <CUnit/Basic.h>
/* Run all tests using the basic interface */
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
Using the console runner π€, there is a console interface to run tests:
#include <CUnit/Console.h>
/* Run all tests using the console interface */
CU_console_run_tests();