@agustfricke
C memory managmentBasics

Unit tests

Unit testing in C with µnit

µnit

µnit is a simple and lightweight unit testing framework for C.

It consists of just two files: munit.c and munit.h. Download them and place them in your project directory.

In this guide, we’ll write a small function to calculate the average of three numbers and create unit tests for it using µnit.


Implement the function

Create a file main.c that defines a function get_average:

main.c
#include "main.h"

float get_average(int x, int y, int z) {
  return ((float)(x + y + z)) / 3.0;
}

And the corresponding header file main.h:

main.h
float get_average(int x, int y, int z);

Write unit tests

Now, let’s write some tests in main_test.c:

main_test.c
#include "munit.h"
#include "main.h"

// Test: average of simple integers
static MunitResult test_get_average(const MunitParameter params[], void* data) {
  float result = get_average(3, 4, 5);
  munit_assert_double_equal(result, 4.0, 2);
  return MUNIT_OK;
}

// Test: non-integer average
static MunitResult test_non_integer(const MunitParameter params[], void* data) {
  float result = get_average(3, 3, 5);
  munit_assert_double_equal(result, 11.0 / 3.0, 2);
  return MUNIT_OK;
}

// Test: all numbers equal
static MunitResult test_average_of_same(const MunitParameter params[], void* data) {
  float result = get_average(10, 10, 10);
  munit_assert_double_equal(result, 10.0, 2);
  return MUNIT_OK;
}

// Test: large numbers
static MunitResult test_average_of_big_numbers(const MunitParameter params[], void* data) {
  float result = get_average(1050, 2050, 2075);
  munit_assert_double_equal(result, 1725.0, 2);
  return MUNIT_OK;
}

// Define the test suite
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
  MunitTest tests[] = {
    { "/get_average",       test_get_average,             NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
    { "/get_average_float", test_non_integer,             NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
    { "/get_average_same",  test_average_of_same,         NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
    { "/get_average_big",   test_average_of_big_numbers,  NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
    { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } // End of tests
  };

  MunitSuite suite = {
    "/get_average_tests",   // Suite name
    tests,                  // Tests
    NULL,                   // No sub-suites
    1,                      // Number of iterations
    MUNIT_SUITE_OPTION_NONE // Suite options
  };

  return munit_suite_main(&suite, NULL, argc, argv);
}

Compile and run the tests

Compile everything together with:

gcc main_test.c main.c munit.c -o run_tests

Run the tests:

./run_tests

Example output

Running test suite with seed 0x4aee7deb...
/get_average_tests/get_average       [ OK    ]
/get_average_tests/get_average_float [ OK    ]
/get_average_tests/get_average_same  [ OK    ]
/get_average_tests/get_average_big   [ OK    ]
4 of 4 (100%) tests successful, 0 (0%) test skipped.