Unittests
Building and Running Tests
Section titled “Building and Running Tests”Tests can be built by calling:
cd tests/unittestsmakeIf there are tests for a module you even can build tests specifically for this module:
make tests-<module># e.g.make tests-coreYou then can run the tests by calling
make termor flash them to your board as you would flash any RIOT application to the board.
You can debug your tests by running
make debugand using GDB as usual.
Other Output Formats
Section titled “Other Output Formats”Other output formats using embUnit’s textui library are available by setting the environment variable OUTPUT:
- Compiler:
OUTPUT="COMPILER" - Text:
OUTPUT="TEXT" - XML:
OUTPUT="XML" - Color:
OUTPUT="COLOR"(like default, but with red/green output) - Colored-Text:
OUTPUT="COLORTEXT"(likeTEXT, but with red/green output)
Compile Example
Section titled “Compile Example”OUTPUT="COMPILER" make tests-coremake term(only outputs in case of test failures)
Text Example
Section titled “Text Example”OUTPUT="TEXT" make tests-coremake term- core_bitarithm_tests1) OK test_SETBIT_null_null2) OK test_SETBIT_null_limit3) ...- core_clist_tests25) ...- ...
OK (... tests)XML Example
Section titled “XML Example”OUTPUT="XML" make tests-coremake term<?xml version="1.0" encoding='shift_jis' standalone='yes' ?><TestRun><core_bitarithm_tests><Test id="1"><Name>test_SETBIT_null_null</Name></Test><Test id="2"><Name>test_SETBIT_null_limit</Name></Test>...</core_bitarithm_tests><core_clist_tests><Test id="25"><Name>test_clist_add_one</Name></Test>...</core_clist_tests><Statistics><Tests>...</Tests></Statistics></TestRun>Writing Unittests
Section titled “Writing Unittests”File Structure
Section titled “File Structure”RIOT uses embUnit for unit testing.
All unittests are organized in tests/unittests and can be built module-wise, if needed.
For each module there exists a tests-<modulename>/tests-<modulename>.h file, at least one C file in tests-<modulename>/ and a tests-<modulename>/Makefile.
It is recommended to add a C file named tests-<modulename>/tests-<modulename>-<headername>.c for every header file that defines functions (or macros) implemented in the module.
If there is only one such header file tests-<modulename>/tests-<modulename>.c should suffice.
Each *.c file should implement a function defined in tests-<modulename>/tests-<modulename>.h, named like
Test *tests_<modulename>_<headername>_tests(void);
/* or respectively */
Test *tests_<modulename>_tests(void);Testing a Module
Section titled “Testing a Module”To write new tests for a module you need to do three things:
- Create a Makefile: add a file
tests-<modulename>/Makefile - Define a test header: add a file
tests-<modulename>/tests-<modulename>.h - Implement tests: for each header file, that defines a function or macro implemented or related to the module, add a file
tests-<modulename>/tests-<modulename>-<headername>.cortests-<modulename>/tests-<modulename>.cif there is only one header.
Create a Makefile
Section titled “Create a Makefile”The Makefile should have the following content:
include $(RIOTBASE)/Makefile.baseDefine a Test Header.
Section titled “Define a Test Header.”The test header tests-<modulename>/tests-<module>.h of a module you add to tests/unittests/ should have the following structure
/* * SPDX-FileCopyrightText: <year> <author> * SPDX-License-Identifier: LGPL-2.1-only */
#pragma once
/** * @addtogroup unittests * @{ * * @file * @brief Unittests for the ``module`` module * * @author <author> */
#include "embUnit/embUnit.h"
#ifdef __cplusplusextern "C" {#endif
/** * @brief Generates tests for <header1>.h * * @return embUnit tests if successful, NULL if not. */Test *tests_<module>_<header1>_tests(void);
/** * @brief Generates tests for <header2>.h * * @return embUnit tests if successful, NULL if not. */Test *tests_<module>_<header2>_tests(void);
/* ... */
#ifdef __cplusplus}#endif
/** @} */Implement Tests
Section titled “Implement Tests”Every tests-<modulename>/tests-<module>*.c file you add to tests/unittests/ should have the following structure:
/* * SPDX-FileCopyrightText: <year> <author> * SPDX-License-Identifier: LGPL-2.1-only */
/* clib includes */
#include "embUnit.h"
#include "<header>.h"
#include "tests-<module>.h"
/* your macros */
/* your global variables */
static void set_up(void){ /* omit if not needed */}
static void tear_down(void){ /* omit if not needed */}
static void test_<function1>_<what1>(void) { /* ... */
TEST_ASSERT(/* ... */);}
static void test_<function1>_<what2>(void) { /* ... */
TEST_ASSERT(/* ... */);}
/* ... */
static void test_<function2>_<what1>(void) { /* ... */
TEST_ASSERT(/* ... */);}
static void test_<function2>_<what2>(void) { /* ... */
TEST_ASSERT(/* ... */);}
/* ... */
Test *tests_<module>_<header>_tests(void){ EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(test_<function1>_<what1>), new_TestFixture(test_<function1>_<what2>), new_TestFixture(test_<function2>_<what1>), new_TestFixture(test_<function2>_<what2>), /* ... */ };
EMB_UNIT_TESTCALLER(<module>_<header>_tests, set_up, tear_down, fixtures); /* set up and tear down function can be NULL if omitted */
return (Test *)&<module>_<header>_tests;}The following assertion macros are available via embUnit
| Assertion | Description |
|---|---|
TEST_ASSERT_EQUAL_STRING(expected,actual)
|
Assert that strings actual and expected are equivalent |
TEST_ASSERT_EQUAL_INT(expected,actual)
|
Assert that integers actual and expected are equivalent |
TEST_ASSERT_NULL(pointer)
|
Assert that pointer == NULL
|
TEST_ASSERT_NOT_NULL(pointer)
|
Assert that pointer != NULL
|
TEST_ASSERT_MESSAGE(condition, message)
|
Assert that condition is TRUE (non-zero) or output customized message on failure.
|
TEST_ASSERT(condition)
|
Assert that condition is TRUE (non-zero)
|
TEST_FAIL(message)
|
Register a failed assertion with the specified message. No logical test is performed. |
Out of Tree Unittests
Section titled “Out of Tree Unittests”Export the environment variable EXTERNAL_UNITTEST_DIRS that contains a space
separated list of out-of-tree unittests to also include in the test. The tests
will be treated the exact same way as tests in this folder and must follow the
same naming convention (each folder in EXTERNAL_UNITTEST_DIRS should have
tests-<name> folders containing the unittests).
This feature works best with EXTERNAL_MODULE_DIRS that contain the code the
external unittests should cover.