`UNITTESTS/mbed_unittest.py` contains testing scripts for Mbed OS unit testing. Mbed CLI supports unit testing through `mbed test --unittests` command with the same arguments.
Unit tests can be run separately from each executable or by using ctest test runner. Run ctest with make program using target test. Options can be passed to ctest using ARGS argument. See [ctest manual](https://cmake.org/cmake/help/v3.0/manual/ctest.1.html) for more information.
Run ctest on test suite level:
```
{MAKE_PROGRAM} test -C [RELATIVE PATH TO BUILD DIRECTORY]
```
e.g. `make test -C UNITTESTS/build` or `mingw32-make test -C UNITTESTS/build`
Run ctest verbose (show each test case):
```
{MAKE_PROGRAM} test -C UNITTESTS/build ARGS="-V"
```
Run ctest dashboard test and create test results:
```
{MAKE_PROGRAM} test --C UNITTESTS/build ARGS="-D ExperimentalTest"
```
### Run with GUI test runner
1. Build and/or install *gtest-runner* using the documentation: https://github.com/nholthaus/gtest-runner
2. Run the application, add built test executables into the list and run it.
### Get code coverage
Python tools use gcovr to build code coverage reports. Generate html report `UNITTESTS/build/coverage/index.html` with:
To get coverage for a single test suite, run gcovr separately for suite coverage data directory. See [gcovr documentation](https://gcovr.com/guide.html#filter-options) for more information.
e.g. for features/netsocket/InternetSocket coverage:
The structure of the unit tests directory looks like this:
```
UNITTESTS
├── mbed_unittest.py Python tool for unit testing
├── unit_test Python tool modules
├── CMakeLists.txt CMake project definition file
├── CMakeSettings.json CMake configurations for Visual Studio 2017
├── README.md
├── googletest-CMakeLists.txt.in CMake project definition file for Google Test
│
├── features
│ └── netsocket Directory tree that mirrors Mbed OS root
│ ├── NetworkInterface Name of the class to be tested
│ │ ├── test_NetworkInterface.cpp
│ │ └── unittest.cmake CMake module for unit test
│ └── Socket
│
├── stubs Shared stubs which can be used for tests.
├── target_h Shared headers which can be used for tests.
└── template Templates for creating new unittests
```
Each unit test has an identical directory tree as seen in the Mbed OS root folder. This is not a mandatory requirement but helps to maintain tests. Each class to be tested have their own `unittest.cmake` which is found by `CMakeLists.txt`.
## Creating a unit test
Each class to be tested requires two files for unit testing:
1. C++ unit test source file (e.g. `test_NetworkInterface.cpp`)
2. CMake module file for unit test definition (`unittest.cmake`)
A unit test definition file `unittest.cmake` requires variables to be set for a test to be configured. File source paths in `unittest.cmake` files need to be relative to the unit test folder and `CMakeLists.txt`.
* **unittest-includes** - Include paths for headers needed to build the tests in addition to the base include paths listed in [CMakeLists.txt](CMakeLists.txt). Optional.
* **unittest-sources** - Mbed OS source files and stubs included for the build.
* **unittest-test-sources** - Unit test source files.
The generator script only creates the files required for a unit test. It does not write unit tests automatically nor does it handle source dependencies.
#### Create files manually
For example to create a unit test for `rtos/Semaphore.cpp`:
1. Create a directory for unit test files in `UNITTESTS/rtos/Semaphore`.
2. Create a test definition file `UNITTESTS/rtos/Semaphore/unittest.cmake` with the following content:
```
set(unittest-sources
stubs/mbed_assert.c
../rtos/Semaphore.cpp
)
set(unittest-test-sources
rtos/Semaphore/test_Semaphore.cpp
)
```
3. Create a test source file `UNITTESTS/rtos/Semaphore/test_Semaphore.cpp` with the following content: