From 10b96f06a3313189bd31f1d88a56b120c1305d06 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Fri, 20 Feb 2015 17:02:28 +0100 Subject: [PATCH] doc: import unittest documentation from wiki --- tests/unittests/README.md | 321 +++++++++++++++++++++++++++++++++++++- 1 file changed, 319 insertions(+), 2 deletions(-) diff --git a/tests/unittests/README.md b/tests/unittests/README.md index df880d6d30..953f3ba4f3 100644 --- a/tests/unittests/README.md +++ b/tests/unittests/README.md @@ -1,6 +1,323 @@ # Unittests -see [Wiki][Testing-RIOT] +## Building and running tests +Tests can be built by calling: +```bash +cd tests/unittests +make +``` - [Testing-RIOT]: https://github.com/RIOT-OS/RIOT/wiki/Testing-RIOT +If there are tests for a module you even can build tests specifically for this module: + +```bash +make tests- +# e.g. +make tests-core +``` + +You then can run the tests by calling + +```bash +make term +``` + +or flash them to your board as you would flash any RIOT application to the board (see [[board documentation|RIOT-Platforms]]). + +### Other output formats +Other output formats using [*embUnit*](http://embunit.sourceforge.net/)'s ``textui`` library are available by setting the environment variable ``OUTPUT``: + +* Compiler: ``OUTPUT="COMPILER"`` +* Text: ``OUTPUT="TEXT"`` +* XML: ``OUTPUT="XML"`` + +#### Compile example +```bash +OUTPUT="COMPILER" make tests-core +make term +``` + +(only outputs in case of test failures) + +#### Text example +```bash +OUTPUT="TEXT" make tests-core +make term +``` + +``` +- core_bitarithm_tests +1) OK test_SETBIT_null_null +2) OK test_SETBIT_null_limit +3) ... +- core_clist_tests +25) ... +- ... + +OK (... tests) +``` + +#### XML example +```bash +OUTPUT="XML" make tests-core +make term +``` + +```XML + + + + +test_SETBIT_null_null + + +test_SETBIT_null_limit + +... + + + +test_clist_add_one + +... + + +... + + +``` + +## Writing unit tests +### File struture +RIOT uses [*embUnit*](http://embunit.sourceforge.net/) for unit testing. +All unit tests are organized in ``tests/unittests`` and can be build module-wise, if needed. +For each module there exists a ``tests-/tests-.h`` file, at least one C file in ``tests-/`` and a ``tests-/Makefile``. +It is recommended to add a C file named ``tests-/tests--.c`` for every header file that defines functions (or macros) implemented in the module. +If there is only one such header file ``tests-/tests-.c`` should suffice. + +Each ``*.c`` file should implement a function defined in ``tests-/tests-.h``, named like + +```C +Test *tests___tests(void); + +/* or respectively */ + +Test *tests__tests(void); +``` + +### Testing a module +To write new tests for a module you need to do three things: + +1. **[Create a Makefile](#create-a-makefile)**: add a file ``tests-/Makefile`` +2. **[Define a test header](#define-a-test-header)**: add a file ``tests-/tests-.h`` +3. **[Implement tests](#implement-tests)**: for each header file, that defines a function or macro implemented or related to the module, add a file ``tests-/tests--.c`` or ``tests-/tests-.c`` if there is only one header. + +#### Create a Makefile +The Makefile should have the following content: + +```Makefile +include $(RIOTBASE)/Makefile.base +``` + +#### Define a test header. +The test header ``tests-/tests-.h`` of a module you add to ``tests/unittests/`` should have the following structure + +```C +/* + * Copyright (C) + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file tests-.h + * @brief Unittests for the ``module`` module + * + * @author + */ +#ifndef __TESTS__H_ +#define __TESTS__H_ +#include "embUnit/embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Generates tests for .h + * + * @return embUnit tests if successful, NULL if not. + */ +Test *tests___tests(void); + +/** + * @brief Generates tests for .h + * + * @return embUnit tests if successful, NULL if not. + */ +Test *tests___tests(void); + +/* ... */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TESTS__H_ */ +/** @} */ +``` + +#### Implement tests +Every ``tests-/tests-*.c`` file you add to ``tests/unittests/`` should have the following structure: + +```C +/* + * Copyright (C) + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/* clib includes */ + +#include "embUnit/embUnit.h" + +#include "
.h" + +#include "tests-.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__(void) { + /* ... */ + + TEST_ASSERT(/* ... */); +} + +static void test__(void) { + /* ... */ + + TEST_ASSERT(/* ... */); +} + +/* ... */ + +static void test__(void) { + /* ... */ + + TEST_ASSERT(/* ... */); +} + +static void test__(void) { + /* ... */ + + TEST_ASSERT(/* ... */); +} + +/* ... */ + +Test *tests__
_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test__), + new_TestFixture(test__), + new_TestFixture(test__), + new_TestFixture(test__), + /* ... */ + }; + + EMB_UNIT_TESTCALLER(_
_tests, "_
_tests", + tests__
_set_up, + tests__
_tear_down, fixtures); + /* set up and tear down function can be NULL if omitted */ + + return (Test *)&_
; +} +``` + +The following assertion macros are available via *embUnit* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AssertionDescription
+ 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. +