New in version 3.0: (PlatformIO Plus)
Unit Testing (wiki) is a software testing method by which individual units of source code, sets of one or more MCU program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use. Unit testing finds problems early in the development cycle.
Demo of Local & Embedded: Calculator.
Get started with STM32Cube HAL and Nucleo-F401RE: debugging and unit testing
ThingForward: Embedded Testing with PlatformIO – Part 3: Remoting
ThingForward: Embedded Testing with PlatformIO – Part 4: Continuous Integration
ThingForward, Webinar: Unit Testing for Embedded with PlatformIO and Qt Creator
For the other examples and source code please follow to PlatformIO Unit Testing Examples repository.
PIO Unit Testing Engine can be configured from Project Configuration File platformio.ini
PIO Unit Testing Engine builds a test program for a host machine using Native development platform. This test could be run only with the desktop or Continuous Integration VM instance.
Note
PlatformIO does not install any toolchains automatically for
Native and requires GCC
toolchain to be installed
on your host machine.
Please open Terminal and check that the gcc
command is installed.
PIO Unit Testing Engine builds a special firmware for a target device (board) and program it. Then, it connects to this device using configured Serial test_port and communicate via test_transport. Finally, it runs test on an embedded side, collects results, analyzes them and provides a summary on a host machine side (desktop).
Note
Please note that the PIO Unit Testing Engine uses the first available Serial/UART
implementation (depending on a framework) as a
communication interface between the PIO Unit Testing Engine and target device. If you use
Serial
in your project libraries, please wrap/hide Serial-based blocks
with #ifndef UNIT_TEST
macro.
Also, you can create custom test_transport and implement base interface.
Test Runner allows you to process specific environments or ignore a test using “Glob patterns”. You can also ignore a test for specific environments using a test_ignore option from Project Configuration File platformio.ini.
Allows you to run a test on a host machine or on a target device (board) which is directly connected to the host machine. In this case, you need to use the platformio test command.
Allows you to run test on a remote machine or remote target device (board) without having to depend on OS software, extra software, SSH, VPN or opening network ports. Remote Unit Testing works in pair with PIO Remote™. In this case, you need to use the special command platformio remote test.
PlatformIO supports multiple Continuous Integration systems where you can run unit tests at the each integration stage. See real PlatformIO Remote Unit Testing Example.
Create PlatformIO project using the platformio init command. For Desktop Unit Testing (on a host machine), you need to use Native.
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter, extra scripting
; Upload options: custom port, speed and extra flags
; Library options: dependencies, extra library storages
;
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
;
; Embedded platforms
;
[env:uno]
platform = atmelavr
framework = arduino
board = uno
[env:nodemcu]
platform = espressif8266
framework = arduino
board = nodemcuv2
;
; Desktop platforms (Win, Mac, Linux, Raspberry Pi, etc)
; See https://platformio.org/platforms/native
;
[env:native]
platform = native
Create a test
folder in a root of your project. See test_dir.
Write a test using API. Each test is a small independent
program/firmware with its own main()
or setup()/loop()
functions.
Test should start with UNITY_BEGIN()
and finish with UNITY_END()
calls.
Warning
If your board does not support software reseting via Serial.DTR/RTS
,
you should add >2 seconds delay before UNITY_BEGIN()`.
That time is needed to establish a ``Serial
connection between a host
machine and a target device.
delay(2000); // for Arduino framework
wait(2); // for ARM mbed framework
UNITY_BEGIN();
Place a test in the test
directory. If you have more than one test,
split them into sub-folders. For example, test/test_1/*.[c,cpp,h]
,
test_N/*.[c,cpp,h]
, etc. If there is no such directory in the test``folder,
then |PIOUTE| will treat the source code of ``test
folder as SINGLE test.
Run test using the platformio test command.
Hint
If you have a shared code between your “main” program (from src_dir) and “test” program, please put it into project’s private libraries folder (lib_dir). See Local & Embedded: Calculator example.
Summary of the Unity Test API:
RUN_TEST(func, linenum)
TEST_IGNORE()
TEST_IGNORE_MESSAGE (message)
TEST_PROTECT()
TEST_ABORT()
TEST_ASSERT_TRUE(condition)
TEST_ASSERT_FALSE(condition)
TEST_ASSERT(condition)
TEST_ASSERT_UNLESS(condition)
TEST_FAIL()
TEST_FAIL_MESSAGE(message)
Numerical Assertions: Integers
TEST_ASSERT_EQUAL_INT(expected, actual)
TEST_ASSERT_EQUAL_INT8(expected, actual)
TEST_ASSERT_EQUAL_INT16(expected, actual)
TEST_ASSERT_EQUAL_INT32(expected, actual)
TEST_ASSERT_EQUAL_INT64(expected, actual)
TEST_ASSERT_EQUAL_UINT(expected, actual)
TEST_ASSERT_EQUAL_UINT8(expected, actual)
TEST_ASSERT_EQUAL_UINT16(expected, actual)
TEST_ASSERT_EQUAL_UINT32(expected, actual)
TEST_ASSERT_EQUAL_UINT64(expected, actual)
TEST_ASSERT_EQUAL_HEX(expected, actual)
TEST_ASSERT_EQUAL_HEX8(expected, actual)
TEST_ASSERT_EQUAL_HEX16(expected, actual)
TEST_ASSERT_EQUAL_HEX32(expected, actual)
TEST_ASSERT_EQUAL_HEX64(expected, actual)
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, elements)
TEST_ASSERT_EQUAL(expected, actual)
TEST_ASSERT_INT_WITHIN(delta, expected, actual)
TEST_ASSERT_BITS(mask, expected, actual)
TEST_ASSERT_BITS_HIGH(mask, actual)
TEST_ASSERT_BITS_LOW(mask, actual)
TEST_ASSERT_BIT_HIGH(mask, actual)
TEST_ASSERT_BIT_LOW(mask, actual)
TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual)
TEST_ASSERT_EQUAL_FLOAT(expected, actual)
TEST_ASSERT_EQUAL_DOUBLE(expected, actual)
TEST_ASSERT_EQUAL_STRING(expected, actual)
TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len)
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message)
TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message)
TEST_ASSERT_NULL(pointer)
TEST_ASSERT_NOT_NULL(pointer)
TEST_ASSERT_EQUAL_MEMORY(expected, actual, len)