Test Hierarchy

PlatformIO looks for the tests in the project test_dir. The only folder with a name prefixed by test_ is nominated for unit testing and should be an independent test/application with its own main() function (setup() / loop() for Arduino, app_main() for Espressif IoT Development Framework). Nested folders are supported and will help you to organize your tests.

The root test_dir and a folder of the active test are automatically added to the CPPPATH scope (C Preprocessor Search Path). Also, C/C++ files located in the root of test_dir will be compiled together with the active test source files. The root test_dir is useful for placing configuration and extra C/C++ files related to the Testing Frameworks.


Example of using the filter / ignore option in “platformio.ini” (Project Configuration File) for the Pizza Project below:

[env:myenv]
test_filter = embedded/*
test_ignore = embedded/components/*

will only execute the embedded/stove/test_humidity, embedded/stove/test_temperature test suites and will ignore the embedded/components/sauce/test_tomatos test suite.

Example of Pizza Project

Let’s demystify how PlatformIO handles unit tests using a virtual “Pizza Project” having the following structure:

project_dir
├── include
│   └── pizza_config.h
├── lib
│   ├── Cheese
│   │   ├── include
│   │   │   └── cheese.h
│   │   └── src
│   │       └── cheese.cpp
│   ├── Dough
│   │   ├── include
│   │   │   └── dough.h
│   │   └── src
│   │       └── dough.cpp
│   └── Sauce
│       ├── include
│       │   └── sauce.h
│       └── src
│           └── sauce.cpp
├── platformio.ini
├── src
│   └── baking.cpp
└── test
   ├── embedded
   │   ├── components
   │   │   └── sauce
   │   │       └── test_tomatos
   │   │           └── prepare.cpp
   │   ├── stove
   │   │   ├── test_humidity
   │   │   │   ├── measure.cpp
   │   │   │   └── sensor.cpp
   │   │   └── test_temperature
   │   │       ├── measure.cpp
   │   │       └── sensor
   │   │           ├── sensor.cpp
   │   │           └── sensor.h
   │   ├── unity_config.cpp
   │   └── unity_config.h
   └── test_ingredients
      ├── include
      │   ├── cheese.h
      │   ├── vegetables.h
      │   ├── water.h
      │   ├── wheat.h
      │   └── yeast.h
      └── weighing.cpp

The main source code (“pizza baking”) is located in the src folder. This is a production code. A cooking process consists of multiple subprocesses and depends on the components located in the lib folder. Each pizza’s component can be tested independently using unit testing.

The Pizza Project consists of 4 independent tests:

  1. embedded/components/sauce/test_tomatos

  2. embedded/stove/test_humidity

  3. embedded/stove/test_temperature

  4. test_ingredients

PlatformIO treats each test as an independent micro project with its own source files and subfolders. You can include local header files using the relative paths. For example, the test_ingredients/weighing.cpp source file includes cheese.h as #include <include/cheese.h>.

The unity_config.h and unity_config.cpp files are located in the embedded folder and are common for the embedded/components/sauce/test_tomatos, embedded/stove/test_humidity, and embedded/stove/test_temperature tests. This allows you to run a group of tests only on the embedded target and route a test result output to the custom Serial/UART interface. On the other hand, the test_ingredients test uses the default Unity configuration provided by PlatformIO. For more details, please check the documentation for the Unity testing framework.