![](http://maximus-embedded.uk/wp-content/uploads/2021/04/photo-1593955654387-9dcbc8ef8071-1024x653.jpg)
Adding tests to your firmware need not be a chore. With a little time spent on setting up the environment beforehand, tests can run after each compilation to quickly validate any change in expected behaviour.
PREPARATION
Linux Users – Install the required packages from the command line:
sudo apt install gcc python curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python get-pip.py
sudo pip install gcovr
sudo pip install gcovr --upgrade
Windows Users – Install the packages manually:
Use the MinGW package manager to install GCC: http://mingw-w64.org/doku.php
Install python: https://www.python.org/
PIP: https://pypi.org/project/pip/
Gcovr: https://gcovr.com/en/4.1/installation.html
[Note that the examples shown here require gcovr version 4.1]
After installing the above, ensure gcc
, make
, python
and gcovr
are available in the system path:
C:\MinGW\bin
C:\MinGW\msys\1.0\bin
C:\Users\username\AppData\Local\Programs\Python\Python37-32 C:\Users\username\AppData\Local\Programs\Python\Python37-32\Scripts
On either format, a local clone of Unity is required:
git clone https://github.com/ThrowTheSwitch/Unity.git
TESTING
Tests are made up from different components:
- Source code under test
- Unit tests
- Mocks
- Test Runners (look in the Unity documentation for more details about these)
- Unity itself
The following makefile extract shows the build sequence, given two source files business_logic.c and eeprom.c
#unity
$(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(UNITY_ROOT)/src/unity.c -o unity.o $(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(UNITY_ROOT)/extras/fixture/src/unity_fixture.c -o unity_fixture.o
#mocks
$(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) ./mock/spi_mock.c -o spi_mock.o
#source files
$(C_COMPILER) -c $(CFLAGS) $(CFLAGS_COV) $(INC_DIRS) $(SYMBOLS) ../src/business_logic.c -o business_logic.o
$(C_COMPILER) -c $(CFLAGS) $(CFLAGS_COV) $(INC_DIRS) $(SYMBOLS) ../src/eeprom.c -o eeprom.o
#test files
$(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) ./business_logic_test.c -o business_logic_test.o
$(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) ./eeprom_test.c -o eeprom_test.o
#test runners
$(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) ./test_runners/business_logic_test_runner.c -o business_logic_test_runner.o
$(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) ./test_runners/eeprom_test_runner.c -o eeprom_test_runner.o $(C_COMPILER) -c $(CFLAGS) $(INC_DIRS) $(SYMBOLS) ./test_runners/all_tests.c -o all_tests.o
$(C_COMPILER) $(CFLAGS) $(CFLAGS_COV) $(INC_DIRS) $(SYMBOLS) \
unity.o \
unity_fixture.o \
business_logic.o \
eeprom.o \
spi_mock.o \
business_logic_test.o \
eeprom_test.o \
business_logic_test_runner.o \
eeprom_test_runner.o \
all_tests.o -o $(TARGET)
Where:
C_COMPILER=gcc CFLAGS=-std=c99 CFLAGS += -Wall CFLAGS += -Wextra CFLAGS += -Wpointer-arith CFLAGS += -Wcast-align CFLAGS += -Wwrite-strings CFLAGS += -Wswitch-default CFLAGS += -Wunreachable-code CFLAGS += -Winit-self CFLAGS += -Wmissing-field-initializers CFLAGS += -Wno-unknown-pragmas CFLAGS += -Wstrict-prototypes CFLAGS += -Wundef CFLAGS += -Wold-style-definition CFLAGS += -DUNIT_TEST CFLAGS_COV=-fprofile-arcs CFLAGS_COV+=-ftest-coverage
Notice the DUNIT_TEST
flag, this allows the source files to abstract away any hardware dependencies and use mocks in their place.
Hopefully there now exists an executable which can be ran. Launching the executable will show how many test passes and failures exist.
./test.exe Unity test run 1 of 1 …….
-----------------------
7 Tests 0 Failures 0 Ignored OK
Now get the test coverage using gcovr
gcovr -r . --html-details -o index.html gcovr -r . -s