Library for MQTT

Committer:
pavleradojkovic
Date:
Mon Jun 20 16:24:43 2022 +0000
Revision:
0:ba7e439238ab
Inital commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pavleradojkovic 0:ba7e439238ab 1 ## Unit testing
pavleradojkovic 0:ba7e439238ab 2
pavleradojkovic 0:ba7e439238ab 3 This document describes how to write and use unit tests for Arm Mbed OS.
pavleradojkovic 0:ba7e439238ab 4
pavleradojkovic 0:ba7e439238ab 5 ### Introduction
pavleradojkovic 0:ba7e439238ab 6
pavleradojkovic 0:ba7e439238ab 7 Unit tests test code in small sections on a host machine. Unlike other testing tools, unit testing doesn't require embedded hardware or need to build a full operating system. Because of this, unit testing can result in faster tests than other tools. Unit testing happens in a build environment where you test each C or C++ class or module in isolation. Build test suites into separate test binaries and stub all access outside to remove dependencies on any specific embedded hardware or software combination. This allows you to complete tests using native compilers on the build machine.
pavleradojkovic 0:ba7e439238ab 8
pavleradojkovic 0:ba7e439238ab 9 ### Prerequisites
pavleradojkovic 0:ba7e439238ab 10
pavleradojkovic 0:ba7e439238ab 11 Please install the following dependencies to use Mbed OS unit testing:
pavleradojkovic 0:ba7e439238ab 12
pavleradojkovic 0:ba7e439238ab 13 * GNU toolchains.
pavleradojkovic 0:ba7e439238ab 14 * GCC 6 or later. We recommend you use MinGW-W64 on Windows, but any Windows port of the above GCC versions works. Default compilers can be used on Mac OS instead of GCC to shorten build times, but code coverage results can differ.
pavleradojkovic 0:ba7e439238ab 15 * CMake 3.0 or newer.
pavleradojkovic 0:ba7e439238ab 16 * Python 2.7.x, 3.5 or newer.
pavleradojkovic 0:ba7e439238ab 17 * Pip 10.0 or newer.
pavleradojkovic 0:ba7e439238ab 18 * Gcovr 4.1 or newer.
pavleradojkovic 0:ba7e439238ab 19 * Arm Mbed CLI 1.8.0 or newer.
pavleradojkovic 0:ba7e439238ab 20
pavleradojkovic 0:ba7e439238ab 21 Detailed instructions for supported operating systems are below.
pavleradojkovic 0:ba7e439238ab 22
pavleradojkovic 0:ba7e439238ab 23 #### Installing dependencies on Debian or Ubuntu
pavleradojkovic 0:ba7e439238ab 24
pavleradojkovic 0:ba7e439238ab 25 In a terminal window:
pavleradojkovic 0:ba7e439238ab 26
pavleradojkovic 0:ba7e439238ab 27 1. `sudo apt-get -y install build-essential cmake`
pavleradojkovic 0:ba7e439238ab 28 1. Install Python and Pip with:
pavleradojkovic 0:ba7e439238ab 29
pavleradojkovic 0:ba7e439238ab 30 ```
pavleradojkovic 0:ba7e439238ab 31 sudo apt-get -y install python python-setuptools
pavleradojkovic 0:ba7e439238ab 32 sudo easy_install pip
pavleradojkovic 0:ba7e439238ab 33 ```
pavleradojkovic 0:ba7e439238ab 34
pavleradojkovic 0:ba7e439238ab 35 1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
pavleradojkovic 0:ba7e439238ab 36
pavleradojkovic 0:ba7e439238ab 37 #### Installing dependencies on macOS
pavleradojkovic 0:ba7e439238ab 38
pavleradojkovic 0:ba7e439238ab 39 In a terminal window:
pavleradojkovic 0:ba7e439238ab 40
pavleradojkovic 0:ba7e439238ab 41 1. Install [Homebrew](https://brew.sh/).
pavleradojkovic 0:ba7e439238ab 42 1. Install Xcode Command Line Tools with `xcode-select --install`.
pavleradojkovic 0:ba7e439238ab 43 1. Install CMake with: `brew install cmake`.
pavleradojkovic 0:ba7e439238ab 44 1. Install Python and Pip:
pavleradojkovic 0:ba7e439238ab 45
pavleradojkovic 0:ba7e439238ab 46 ```
pavleradojkovic 0:ba7e439238ab 47 brew install python
pavleradojkovic 0:ba7e439238ab 48 sudo easy_install pip
pavleradojkovic 0:ba7e439238ab 49 ```
pavleradojkovic 0:ba7e439238ab 50
pavleradojkovic 0:ba7e439238ab 51 1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
pavleradojkovic 0:ba7e439238ab 52 1. (Optional) Install GCC with `brew install gcc`.
pavleradojkovic 0:ba7e439238ab 53
pavleradojkovic 0:ba7e439238ab 54 #### Installing dependencies on Windows
pavleradojkovic 0:ba7e439238ab 55
pavleradojkovic 0:ba7e439238ab 56 In a terminal window:
pavleradojkovic 0:ba7e439238ab 57
pavleradojkovic 0:ba7e439238ab 58 1. Download and install MinGW-W64 from [SourceForge](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/).
pavleradojkovic 0:ba7e439238ab 59 1. Download CMake binaries from https://cmake.org/download/, and run the installer.
pavleradojkovic 0:ba7e439238ab 60 1. Download Python 2.7 or Python 3 from https://www.python.org/getit/, and run the installer.
pavleradojkovic 0:ba7e439238ab 61 1. Add MinGW, CMake and Python into system PATH.
pavleradojkovic 0:ba7e439238ab 62 1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
pavleradojkovic 0:ba7e439238ab 63
pavleradojkovic 0:ba7e439238ab 64 ### Test code structure
pavleradojkovic 0:ba7e439238ab 65
pavleradojkovic 0:ba7e439238ab 66 Find unit tests in the Mbed OS repository under the `UNITTESTS` folder. We recommend unit test files use an identical directory path as the file under test. This makes it easier to find unit tests for a particular class or a module. For example, if the file you're testing is `some/example/path/ClassName.cpp`, then all the test files are in the `UNITTESTS/some/example/path/ClassName` directory. Each test suite needs to have its own `unittest.cmake` file for test configuration.
pavleradojkovic 0:ba7e439238ab 67
pavleradojkovic 0:ba7e439238ab 68 All the class stubs should be located in the `UNITTESTS/stubs` directory. A single stub class can be used by multiple test suites and should follow the naming convention `ClassName_stub.cpp` for the source file, and `ClassName_stub.h` for the header file. Use the actual header files for the unit tests, and don't stub headers if possible. The stubbed headers reside in the `UNITTESTS/target_h` directory.
pavleradojkovic 0:ba7e439238ab 69
pavleradojkovic 0:ba7e439238ab 70 #### Test discovery
pavleradojkovic 0:ba7e439238ab 71
pavleradojkovic 0:ba7e439238ab 72 Registering unit tests to run happens automatically, and the test runner handles registration. However, test files do not automatically build. Build unit tests with a separate system that searches for unit tests under the `UNITTESTS` directory.
pavleradojkovic 0:ba7e439238ab 73
pavleradojkovic 0:ba7e439238ab 74 For the build system to find and build any test suite automatically, include a unit test configuration file named `unittest.cmake` for each unit test suite. This configuration file lists all the source files required for the test build.
pavleradojkovic 0:ba7e439238ab 75
pavleradojkovic 0:ba7e439238ab 76 #### Test names
pavleradojkovic 0:ba7e439238ab 77
pavleradojkovic 0:ba7e439238ab 78 The build system automatically generates names of test suites. The name is constructed by taking a relative file path from the UNITTESTS directory to the test directory and replacing path separators with dashes. For example, the test suite name for `some/example/path/ClassName.cpp` is `some-example-path-ClassName`. Suite names are used when deciding which test suites to run.
pavleradojkovic 0:ba7e439238ab 79
pavleradojkovic 0:ba7e439238ab 80 ### Unit testing with Mbed CLI
pavleradojkovic 0:ba7e439238ab 81
pavleradojkovic 0:ba7e439238ab 82 Mbed CLI supports unit tests through the `mbed test --unittests` command. For information on using Mbed CLI, please see the [CLI documentation](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html).
pavleradojkovic 0:ba7e439238ab 83
pavleradojkovic 0:ba7e439238ab 84 ### Writing unit tests
pavleradojkovic 0:ba7e439238ab 85
pavleradojkovic 0:ba7e439238ab 86 A unit tests suite consists of one or more test cases. The test cases should cover all the functions in a class under test. All the external dependencies are stubbed including the other classes in the same module. Avoid stubbing header files. Finally, analyze code coverage to ensure all code is tested, and no dead code is found.
pavleradojkovic 0:ba7e439238ab 87
pavleradojkovic 0:ba7e439238ab 88 Unit tests are written using [Google Test v1.8.1](https://github.com/google/googletest/releases/tag/release-1.8.1).
pavleradojkovic 0:ba7e439238ab 89
pavleradojkovic 0:ba7e439238ab 90 Please see the [documentation for Google Test](https://github.com/google/googletest/blob/master/googletest/docs/primer.md) to learn how to write unit tests using its framework. See the [documentation for Google Mock](https://github.com/google/googletest/blob/master/googlemock/docs/Documentation.md) if you want to write and use C++ mock classes instead of stubs.
pavleradojkovic 0:ba7e439238ab 91
pavleradojkovic 0:ba7e439238ab 92 #### Test suite configuration
pavleradojkovic 0:ba7e439238ab 93
pavleradojkovic 0:ba7e439238ab 94 Create two files in the test directory for each test suite:
pavleradojkovic 0:ba7e439238ab 95
pavleradojkovic 0:ba7e439238ab 96 * Unit test source file (`test_ClassName.cpp`).
pavleradojkovic 0:ba7e439238ab 97 * Unit test configuration file (`unittest.cmake`).
pavleradojkovic 0:ba7e439238ab 98
pavleradojkovic 0:ba7e439238ab 99 List all the required files for the build in the `unittest.cmake` file with paths relative to the `UNITTESTS` folder. Use the following variables to list the source files and include paths:
pavleradojkovic 0:ba7e439238ab 100
pavleradojkovic 0:ba7e439238ab 101 * **unittest-includes**: List of header include paths. You can use this to extend or overwrite default paths listed in `UNITTESTS/CMakeLists.txt`.
pavleradojkovic 0:ba7e439238ab 102 * **unittest-sources**: List of files under test.
pavleradojkovic 0:ba7e439238ab 103 * **unittest-test-sources**: List of test sources and stubs.
pavleradojkovic 0:ba7e439238ab 104
pavleradojkovic 0:ba7e439238ab 105 You can also set custom compiler flags and other configurations supported by CMake in `unittest.cmake`.
pavleradojkovic 0:ba7e439238ab 106
pavleradojkovic 0:ba7e439238ab 107 #### Example
pavleradojkovic 0:ba7e439238ab 108
pavleradojkovic 0:ba7e439238ab 109 With the following steps, you can write a simple unit test. This example creates dummy classes to be tested, creates and configures unit tests for a class and stubs all external dependencies.
pavleradojkovic 0:ba7e439238ab 110
pavleradojkovic 0:ba7e439238ab 111 1. Create the following dummy classes in `mbed-os/example`:
pavleradojkovic 0:ba7e439238ab 112
pavleradojkovic 0:ba7e439238ab 113 **MyClass.h**
pavleradojkovic 0:ba7e439238ab 114
pavleradojkovic 0:ba7e439238ab 115 ```
pavleradojkovic 0:ba7e439238ab 116 #ifndef MYCLASS_H_
pavleradojkovic 0:ba7e439238ab 117 #define MYCLASS_H_
pavleradojkovic 0:ba7e439238ab 118
pavleradojkovic 0:ba7e439238ab 119 namespace example {
pavleradojkovic 0:ba7e439238ab 120
pavleradojkovic 0:ba7e439238ab 121 class MyClass {
pavleradojkovic 0:ba7e439238ab 122 public:
pavleradojkovic 0:ba7e439238ab 123 int myFunction();
pavleradojkovic 0:ba7e439238ab 124 };
pavleradojkovic 0:ba7e439238ab 125
pavleradojkovic 0:ba7e439238ab 126 }
pavleradojkovic 0:ba7e439238ab 127
pavleradojkovic 0:ba7e439238ab 128 #endif
pavleradojkovic 0:ba7e439238ab 129 ```
pavleradojkovic 0:ba7e439238ab 130
pavleradojkovic 0:ba7e439238ab 131 **MyClass.cpp**
pavleradojkovic 0:ba7e439238ab 132
pavleradojkovic 0:ba7e439238ab 133 ```
pavleradojkovic 0:ba7e439238ab 134 #include "MyClass.h"
pavleradojkovic 0:ba7e439238ab 135 #include "OtherClass.h"
pavleradojkovic 0:ba7e439238ab 136
pavleradojkovic 0:ba7e439238ab 137 namespace example {
pavleradojkovic 0:ba7e439238ab 138
pavleradojkovic 0:ba7e439238ab 139 int MyClass::myFunction() {
pavleradojkovic 0:ba7e439238ab 140 OtherClass o = OtherClass();
pavleradojkovic 0:ba7e439238ab 141 return o.otherFunction();
pavleradojkovic 0:ba7e439238ab 142 }
pavleradojkovic 0:ba7e439238ab 143
pavleradojkovic 0:ba7e439238ab 144 }
pavleradojkovic 0:ba7e439238ab 145 ```
pavleradojkovic 0:ba7e439238ab 146
pavleradojkovic 0:ba7e439238ab 147 **OtherClass.h**
pavleradojkovic 0:ba7e439238ab 148
pavleradojkovic 0:ba7e439238ab 149 ```
pavleradojkovic 0:ba7e439238ab 150 #ifndef OTHERCLASS_H_
pavleradojkovic 0:ba7e439238ab 151 #define OTHERCLASS_H_
pavleradojkovic 0:ba7e439238ab 152
pavleradojkovic 0:ba7e439238ab 153 namespace example {
pavleradojkovic 0:ba7e439238ab 154
pavleradojkovic 0:ba7e439238ab 155 class OtherClass {
pavleradojkovic 0:ba7e439238ab 156 public:
pavleradojkovic 0:ba7e439238ab 157 int otherFunction();
pavleradojkovic 0:ba7e439238ab 158 };
pavleradojkovic 0:ba7e439238ab 159
pavleradojkovic 0:ba7e439238ab 160 }
pavleradojkovic 0:ba7e439238ab 161
pavleradojkovic 0:ba7e439238ab 162 #endif
pavleradojkovic 0:ba7e439238ab 163 ```
pavleradojkovic 0:ba7e439238ab 164
pavleradojkovic 0:ba7e439238ab 165 **OtherClass.cpp**
pavleradojkovic 0:ba7e439238ab 166
pavleradojkovic 0:ba7e439238ab 167 ```
pavleradojkovic 0:ba7e439238ab 168 #include "OtherClass.h"
pavleradojkovic 0:ba7e439238ab 169
pavleradojkovic 0:ba7e439238ab 170 namespace example {
pavleradojkovic 0:ba7e439238ab 171
pavleradojkovic 0:ba7e439238ab 172 int OtherClass::otherFunction() {
pavleradojkovic 0:ba7e439238ab 173 return 1;
pavleradojkovic 0:ba7e439238ab 174 }
pavleradojkovic 0:ba7e439238ab 175
pavleradojkovic 0:ba7e439238ab 176 }
pavleradojkovic 0:ba7e439238ab 177 ```
pavleradojkovic 0:ba7e439238ab 178
pavleradojkovic 0:ba7e439238ab 179 1. Create a directory for MyClass unit tests in `UNITTESTS/example/MyClass`.
pavleradojkovic 0:ba7e439238ab 180 1. Create a configuration file and a source file for MyClass unit tests in `UNITTESTS/example/MyClass`:
pavleradojkovic 0:ba7e439238ab 181
pavleradojkovic 0:ba7e439238ab 182 **unittest.cmake**
pavleradojkovic 0:ba7e439238ab 183
pavleradojkovic 0:ba7e439238ab 184 ```
pavleradojkovic 0:ba7e439238ab 185 # Add here additional test specific include paths
pavleradojkovic 0:ba7e439238ab 186 set(unittest-includes ${unittest-includes}
pavleradojkovic 0:ba7e439238ab 187 ../example
pavleradojkovic 0:ba7e439238ab 188 )
pavleradojkovic 0:ba7e439238ab 189
pavleradojkovic 0:ba7e439238ab 190 # Add here classes under test
pavleradojkovic 0:ba7e439238ab 191 set(unittest-sources
pavleradojkovic 0:ba7e439238ab 192 ../example/MyClass.cpp
pavleradojkovic 0:ba7e439238ab 193 )
pavleradojkovic 0:ba7e439238ab 194
pavleradojkovic 0:ba7e439238ab 195 # Add here test classes and stubs
pavleradojkovic 0:ba7e439238ab 196 set(unittest-test-sources
pavleradojkovic 0:ba7e439238ab 197 example/MyClass/test_MyClass.cpp
pavleradojkovic 0:ba7e439238ab 198 stubs/OtherClass_stub.cpp
pavleradojkovic 0:ba7e439238ab 199 )
pavleradojkovic 0:ba7e439238ab 200 ```
pavleradojkovic 0:ba7e439238ab 201
pavleradojkovic 0:ba7e439238ab 202 **test_MyClass.cpp**
pavleradojkovic 0:ba7e439238ab 203
pavleradojkovic 0:ba7e439238ab 204 ```
pavleradojkovic 0:ba7e439238ab 205 #include "gtest/gtest.h"
pavleradojkovic 0:ba7e439238ab 206 #include "example/MyClass.h"
pavleradojkovic 0:ba7e439238ab 207
pavleradojkovic 0:ba7e439238ab 208 class TestMyClass : public testing::Test {
pavleradojkovic 0:ba7e439238ab 209 protected:
pavleradojkovic 0:ba7e439238ab 210 example::MyClass *obj;
pavleradojkovic 0:ba7e439238ab 211
pavleradojkovic 0:ba7e439238ab 212 virtual void SetUp()
pavleradojkovic 0:ba7e439238ab 213 {
pavleradojkovic 0:ba7e439238ab 214 obj = new example::MyClass();
pavleradojkovic 0:ba7e439238ab 215 }
pavleradojkovic 0:ba7e439238ab 216
pavleradojkovic 0:ba7e439238ab 217 virtual void TearDown()
pavleradojkovic 0:ba7e439238ab 218 {
pavleradojkovic 0:ba7e439238ab 219 delete obj;
pavleradojkovic 0:ba7e439238ab 220 }
pavleradojkovic 0:ba7e439238ab 221 };
pavleradojkovic 0:ba7e439238ab 222
pavleradojkovic 0:ba7e439238ab 223 TEST_F(TestMyClass, constructor)
pavleradojkovic 0:ba7e439238ab 224 {
pavleradojkovic 0:ba7e439238ab 225 EXPECT_TRUE(obj);
pavleradojkovic 0:ba7e439238ab 226 }
pavleradojkovic 0:ba7e439238ab 227
pavleradojkovic 0:ba7e439238ab 228 TEST_F(TestMyClass, myfunction)
pavleradojkovic 0:ba7e439238ab 229 {
pavleradojkovic 0:ba7e439238ab 230 EXPECT_EQ(obj->myFunction(), 0);
pavleradojkovic 0:ba7e439238ab 231 }
pavleradojkovic 0:ba7e439238ab 232 ```
pavleradojkovic 0:ba7e439238ab 233
pavleradojkovic 0:ba7e439238ab 234 1. Stub all external dependencies. Create the following stub in `UNITTESTS/stubs`:
pavleradojkovic 0:ba7e439238ab 235
pavleradojkovic 0:ba7e439238ab 236 **OtherClass_stub.cpp**
pavleradojkovic 0:ba7e439238ab 237
pavleradojkovic 0:ba7e439238ab 238 ```
pavleradojkovic 0:ba7e439238ab 239 #include "example/OtherClass.h"
pavleradojkovic 0:ba7e439238ab 240
pavleradojkovic 0:ba7e439238ab 241 namespace example {
pavleradojkovic 0:ba7e439238ab 242
pavleradojkovic 0:ba7e439238ab 243 int OtherClass::otherFunction() {
pavleradojkovic 0:ba7e439238ab 244 return 0;
pavleradojkovic 0:ba7e439238ab 245 }
pavleradojkovic 0:ba7e439238ab 246
pavleradojkovic 0:ba7e439238ab 247 }
pavleradojkovic 0:ba7e439238ab 248 ```
pavleradojkovic 0:ba7e439238ab 249
pavleradojkovic 0:ba7e439238ab 250 This example does not use any Mbed OS code, but if your unit tests do, then remember to update header stubs in `UNITTESTS/target_h` and source stubs in `UNITTESTS/stubs` with any missing type or function declarations.
pavleradojkovic 0:ba7e439238ab 251
pavleradojkovic 0:ba7e439238ab 252 ### Building and running unit tests
pavleradojkovic 0:ba7e439238ab 253
pavleradojkovic 0:ba7e439238ab 254 Use Mbed CLI to build and run unit tests. For advanced use, you can run CMake and a Make program directly.
pavleradojkovic 0:ba7e439238ab 255
pavleradojkovic 0:ba7e439238ab 256 #### Build tests directly with CMake
pavleradojkovic 0:ba7e439238ab 257
pavleradojkovic 0:ba7e439238ab 258 1. Create a build directory `mkdir UNITTESTS/build`.
pavleradojkovic 0:ba7e439238ab 259 1. Move to the build directory `cd UNITTESTS/build`.
pavleradojkovic 0:ba7e439238ab 260 1. Run CMake using a relative path to `UNITTESTS` folder as the argument. So from `UNITTESTS/build` use `cmake ..`:
pavleradojkovic 0:ba7e439238ab 261 * Add `-g [generator]` if generating other than Unix Makefiles such in case of MinGW use `-g "MinGW Makefiles"`.
pavleradojkovic 0:ba7e439238ab 262 * Add `-DCMAKE_MAKE_PROGRAM=<value>`, `-DCMAKE_CXX_COMPILER=<value>` and `-DCMAKE_C_COMPILER=<value>` to use a specific Make program and compilers.
pavleradojkovic 0:ba7e439238ab 263 * Add `-DCMAKE_BUILD_TYPE=Debug` for a debug build.
pavleradojkovic 0:ba7e439238ab 264 * Add `-DCOVERAGE=True` to add coverage compiler flags.
pavleradojkovic 0:ba7e439238ab 265 * Add `-Dgtest_disable_pthreads=ON` to run in a single thread.
pavleradojkovic 0:ba7e439238ab 266 * See the [CMake manual](https://cmake.org/cmake/help/v3.0/manual/cmake.1.html) for more information.
pavleradojkovic 0:ba7e439238ab 267 1. Run a Make program to build tests.
pavleradojkovic 0:ba7e439238ab 268
pavleradojkovic 0:ba7e439238ab 269 #### Run tests directly with CTest
pavleradojkovic 0:ba7e439238ab 270
pavleradojkovic 0:ba7e439238ab 271 Run a test binary in the build directory to run a unit test suite. To run multiple test suites at once, use the CTest test runner. Run CTest with `ctest`. Add `-v` to get results for each test case. See the [CTest manual](https://cmake.org/cmake/help/v3.0/manual/ctest.1.html) for more information.
pavleradojkovic 0:ba7e439238ab 272
pavleradojkovic 0:ba7e439238ab 273 #### Run tests with GUI test runner
pavleradojkovic 0:ba7e439238ab 274
pavleradojkovic 0:ba7e439238ab 275 1. Install `gtest-runner` according to the [documentation](https://github.com/nholthaus/gtest-runner).
pavleradojkovic 0:ba7e439238ab 276 1. Run `gtest-runner`.
pavleradojkovic 0:ba7e439238ab 277 1. Add test executables into the list and run.
pavleradojkovic 0:ba7e439238ab 278
pavleradojkovic 0:ba7e439238ab 279 ### Debugging
pavleradojkovic 0:ba7e439238ab 280
pavleradojkovic 0:ba7e439238ab 281 1. Use Mbed CLI to build a debug build. For advanced use, run CMake directly with `-DCMAKE_BUILD_TYPE=Debug`, and then run a Make program.
pavleradojkovic 0:ba7e439238ab 282 1. Run GDB with a test executable as an argument to debug unit tests.
pavleradojkovic 0:ba7e439238ab 283 1. Run tests with Valgrind to analyze the test memory profile.
pavleradojkovic 0:ba7e439238ab 284
pavleradojkovic 0:ba7e439238ab 285 ### Get code coverage
pavleradojkovic 0:ba7e439238ab 286
pavleradojkovic 0:ba7e439238ab 287 Use Mbed CLI to generate code coverage reports. For advanced use, follow these steps:
pavleradojkovic 0:ba7e439238ab 288
pavleradojkovic 0:ba7e439238ab 289 1. Run CMake with both `-DCMAKE_BUILD_TYPE=Debug` and `-DCOVERAGE=True`.
pavleradojkovic 0:ba7e439238ab 290 1. Run a Make program to build the tests.
pavleradojkovic 0:ba7e439238ab 291 1. Run the tests.
pavleradojkovic 0:ba7e439238ab 292 1. Run Gcovr or any other code coverage tool directly in the build directory.
pavleradojkovic 0:ba7e439238ab 293
pavleradojkovic 0:ba7e439238ab 294 ### Troubleshooting
pavleradojkovic 0:ba7e439238ab 295
pavleradojkovic 0:ba7e439238ab 296 **Problem:** Generic problems with CMake or with the build process.
pavleradojkovic 0:ba7e439238ab 297 * **Solution**: Delete the build directory. Make sure that CMake, g++, GCC and a Make program can be found in the path and are correct versions.
pavleradojkovic 0:ba7e439238ab 298
pavleradojkovic 0:ba7e439238ab 299 **Problem:** (Windows) Virus protection identifies files generated by CMake as malicious and quarantines the files.
pavleradojkovic 0:ba7e439238ab 300 * **Solution**: Restore false-positive files from the quarantine.
pavleradojkovic 0:ba7e439238ab 301
pavleradojkovic 0:ba7e439238ab 302 **Problem:** (Windows) Git with shell installation adds sh.exe to the path and then CMake throws an error: sh.exe was found in your PATH. For MinGW make to work correctly, sh.exe must NOT be in your path.
pavleradojkovic 0:ba7e439238ab 303 * **Solution**: Remove sh.exe from the system path.
pavleradojkovic 0:ba7e439238ab 304
pavleradojkovic 0:ba7e439238ab 305 **Problem:** (Mac OS) CMake compiler check fails on Mac OS Mojave when using GCC-8.
pavleradojkovic 0:ba7e439238ab 306 * **Solution**: Make sure gnm (binutils) is not installed. Uninstall binutils with `brew uninstall binutils`.