Unit Testing
Unit testing introduction
Tests are a great way to validate the operation of software and should be a part of any commercial or serious project. electricui-embedded
tests to prevent functionality regressions, catch bugs and let us sleep at night. Some other tools mentioned in this section are more than just unit tests, linting checks and automated fuzzing tests help find potential issues outside the test corpus.
The electricui-embedded/test
directory contains the testing related code and helper scripts. We assume the use of a unix system, and bash-like shell.
We use Unity for tests, along with CMock as part of the Ceedling test suite. This is a Ruby/Rake based system which provides a series of helper utilities for test management, automatic mock creation, and other assistive tools like easy code coverage reports.
Install and preparation
We don't include Ceedling's vendor files in the repo, so first runs need to 're-initalise' the test structure.
- The
test/setup_tests.sh
script helps get started really quickly, helping you get the ceedling gem installed, and re-initalising the project.- You might need to add execution permission first. From
/test
, runchmod +x setup_tests.sh
. - If you don't have ceedling installed, it will prompt to install the ruby gem.
- You might need to add execution permission first. From
- The script will create the relevant files and automatically reject changes to our existing configuration files.
- Once setup is complete, just run
ceedling
orceedling test:all
, results will be printed to the console.
Adding & Modifying tests
The tests are in a series of files in the tests/test/
directory and should provide enough of an example. Ceedling's vendor
folder has docs for Unity, CMock and Ceedling if you need more detailed guides and examples.
Code Coverage Reports
Ceedling includes the helper for this, providing gcov
is available on your system.
ceedling gcov:all
to generate the coverage map, then ceedling utils:gcov
to generate the HTML formatted report which provides line and branch level coverage details.
Lint Analysis
oclint
is used to provide a basic level of static analysis, aimed at identifying code smells and syntactical errors which might cause undesired behaviour or needlessly complex source code.
- Its available in binary format or as sources from the website, or you can use your package manager if its available (
brew install oclint
) etc. - Run
./lint_checks.sh
to run oclint with the library sources. The script applies some small tweaks to the linting ruleset and enables the static analysis functionality. - Results are printed to the console.
Small numbers of P2 and P3 errors are acceptable in certain situations, as the cyclomatic complexity and function length guides are difficult to overcome in some situations without needlessly obscuring functionality behind denser syntax.
The linting tool is best used as a guide or warning while developing, and many low severity warnings don't necessarily require action.
Fuzzing
American Fuzzy Lop, afl-fuzz
is used to generate mutated input data and pass it to the decoder. This allows us to test the effects of potentially underhanded input messages, though this test program is simplistic and slightly naive.
- Install the afl suite by following the install instructions or using your package manager (
brew install afl-fuzz
on OSX,pacman -S afl
for Arch, etc). - Modify the makefile to correctly point to the
afl-gcc
(most *nix systems) orafl-clang
(OSX) build tool to suit your system. - From the
test/fuzz
directory, callmake all
to build an instrumented binary and begin testing. - Wait a while while it attempts various modifications and mutations from the input files.