Skip to content

What it is

Check is a unit testing framework for C that allows developers to write test cases for their code in a simple and structured way. It provides assertions, test fixtures, and test suites to ensure code correctness.

Check allows you to define test cases with `START_TEST` and `END_TEST` macros, group them into test suites, and run them with the `SRunner`. It supports setup/teardown functions for initializing and cleaning resources before and after tests.

Installation

sudo apt install check

Getting started

The smallest useful thing you can do with it, and what each part means.

Simple test case
#include <check.h>
#include <stdlib.h>

int add(int a, int b) { return a + b; }

START_TEST(test_add) {
    ck_assert_int_eq(add(2, 3), 5);
}
END_TEST

int main(void) {
    Suite *s = suite_create("MySuite");
    TCase *tc = tcase_create("Core");
    tcase_add_test(tc, test_add);
    suite_add_tcase(s, tc);

    SRunner *sr = srunner_create(s);
    srunner_run_all(sr, CK_NORMAL);
    int number_failed = srunner_ntests_failed(sr);
    srunner_free(sr);
    return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
Defines a simple test for the `add` function using `ck_assert_int_eq` and runs it via a test suite and runner.
Using setup and teardown
START_TEST(test_example) {
    ck_assert_int_eq(42, *ptr);
}
END_TEST

void setup(void) { ptr = malloc(sizeof(int)); *ptr = 42; }
void teardown(void) { free(ptr); }
Demonstrates initializing resources before a test and cleaning them up afterward.

Advanced usage

Where the library earns its place over a simpler alternative.

Multiple test cases in a suite
START_TEST(test_add) { ck_assert_int_eq(add(2,3), 5); } END_TEST
START_TEST(test_subtract) { ck_assert_int_eq(subtract(5,3), 2); } END_TEST
TCase *tc = tcase_create("Math");
tcase_add_test(tc, test_add);
tcase_add_test(tc, test_subtract);
Suite *s = suite_create("MathSuite");
suite_add_tcase(s, tc);
Groups multiple test cases into a single test suite for organized execution.
Skipping tests
START_TEST(test_skip) { ck_abort_msg("Skipping this test"); } END_TEST
Shows how to skip a test dynamically with a custom message.
Floating-point assertions
START_TEST(test_float) { ck_assert_double_eq_tol(3.1415, pi, 0.0001); } END_TEST
Demonstrates asserting approximate equality for floating-point values with a tolerance.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Segmentation fault in a test
Check pointer usage and ensure proper memory allocation/deallocation in setup and test cases.
Assertion failures
Review the failed assertion message and debug the logic of the function under test.

Best practices

  • Group related test cases into suites for easier management.
  • Use setup/teardown functions to handle resource allocation and cleanup.
  • Keep tests independent to avoid side effects between tests.
  • Use meaningful assertion macros (`ck_assert`, `ck_assert_int_eq`, `ck_assert_double_eq_tol`, etc.) for clarity.
  • Run tests frequently during development to catch regressions early.

Background

Why it exists, and what it was reacting to.

Check was created to provide an easy-to-use framework for C unit testing, similar to frameworks available in other languages like JUnit for Java. It supports test cases, setup/teardown functions, and reporting, helping C developers maintain robust and reliable code.