Skip to content

Commit eff6816

Browse files
maribucrasbe
andcommitted
tests/unittests: allow out-of-tree tests
This adds and documents the new `EXTERNAL_UNIT_TEST_DIRS` environment variable that allows including out-of-tree unit tests. The intention is to allow users of `EXTERNAL_MODULE_DIRS` to also provide corresponding unit tests and run them all with a single test app. Co-authored-by: crasbe <[email protected]>
1 parent 02515a1 commit eff6816

File tree

13 files changed

+174
-8
lines changed

13 files changed

+174
-8
lines changed

doc/guides/advanced_tutorials/creating_application.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,11 @@ APPLICATION = my_app
343343
PROJECT_BASE ?= $(CURDIR)/../..
344344
include $(PROJECT_BASE)/Makefile.include
345345
```
346+
347+
### Unit Tests for External Modules
348+
349+
When writing external modules, it can be helpful to make use of the existing
350+
unit test infrastructure in `tests/unittests` to run both upstream unit tests
351+
as well as downstream project-specific unit tests in a single app. For this the
352+
environment variable `EXTERNAL_UNITTEST_DIRS` can be used to list directories
353+
(separated by a space) to additional unit tests.

makefiles/app_dirs.blacklist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ tests/build_system/external_board_native/external_boards/
1111
tests/build_system/external_module_dirs/external_modules/
1212
tests/build_system/external_pkg_dirs/external_pkgs/
1313
tests/build_system/kconfig/external_modules/
14+
tests/build_system/external_unittests/external_tests_dir/
15+
tests/build_system/external_unittests/tests-in_tree
1416
tests/build_system/kconfig/external_pkgs/
1517
tests/periph/qdec/boards_modded/
1618
tests/pkg/openwsn_sock_udp/external_modules/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Run this only on native64 / native, as this rather tests the build system
2+
# than the code actually run.
3+
4+
BOARD_WHITELIST := native native64
5+
6+
EXTERNAL_UNITTEST_DIRS := $(CURDIR)/external_tests_dir
7+
8+
# Build upon tests/unittests:
9+
RIOTBASE ?= $(CURDIR)/../../..
10+
UNIT_TESTS_DIR := $(CURDIR)/../../unittests
11+
include ../../unittests/Makefile
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
External Unit Tests
2+
===================
3+
4+
This test apps provides two trivial unit tests: One provided internally in the
5+
folder of this unit tests apps and one provided externally via a variable.
6+
Since the test only validates correct operation of the build system, there is
7+
little value in running it on more than one board. For this reason, the app is
8+
limited to be build only for native / native64.
9+
10+
Implementation Details
11+
----------------------
12+
13+
The two tests contain a reference to a variable of the other tests, so that
14+
the app will not link if only if both of the unit tests are available at
15+
link time (or none). In addition, the python test runner will check that two
16+
tests are executed (to rule out that none was available).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(RIOTBASE)/Makefile.base
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2025 ML!PA Consulting GmbH
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
#include <stdio.h>
10+
11+
#include "embUnit.h"
12+
13+
const unsigned external_test_was_linked_in = 1;
14+
15+
static void test_internal_test_was_linked_in(void)
16+
{
17+
extern const unsigned internal_test_was_linked_in;
18+
TEST_ASSERT_EQUAL_INT(1, internal_test_was_linked_in);
19+
}
20+
21+
static Test *out_of_tree_tests(void)
22+
{
23+
EMB_UNIT_TESTFIXTURES(fixtures) {
24+
new_TestFixture(test_internal_test_was_linked_in),
25+
};
26+
27+
EMB_UNIT_TESTCALLER(_out_of_tree_tests, NULL, NULL, fixtures);
28+
29+
return (Test *)&_out_of_tree_tests;
30+
}
31+
32+
void tests_out_of_tree(void)
33+
{
34+
TESTS_RUN(out_of_tree_tests());
35+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../unittests/main.c
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../unittests/map.h
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(RIOTBASE)/Makefile.base
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2025 ML!PA Consulting GmbH
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
#include <stdio.h>
10+
11+
#include "embUnit.h"
12+
13+
const unsigned internal_test_was_linked_in = 1;
14+
15+
static void test_external_test_was_linked_in(void)
16+
{
17+
extern const unsigned external_test_was_linked_in;
18+
TEST_ASSERT_EQUAL_INT(1, external_test_was_linked_in);
19+
}
20+
21+
static Test *in_tree_tests(void)
22+
{
23+
EMB_UNIT_TESTFIXTURES(fixtures) {
24+
new_TestFixture(test_external_test_was_linked_in),
25+
};
26+
27+
EMB_UNIT_TESTCALLER(_in_tree_tests, NULL, NULL, fixtures);
28+
29+
return (Test *)&_in_tree_tests;
30+
}
31+
32+
void tests_in_tree(void)
33+
{
34+
TESTS_RUN(in_tree_tests());
35+
}

0 commit comments

Comments
 (0)