Raspberry Pico: Unit Test Framework for Your Projects

Installation

wget https://cmocka.org/files/1.1/cmocka-1.1.5.tar.xz
tar xvf cmocka-1.1.5.tar.xz
cd cmocka-1.1.5
mkdir build
cd build
cmake ..
make
Scanning dependencies of target cmocka
[ 4%] Building C object src/CMakeFiles/cmocka.dir/cmocka.c.o
[ 9%] Linking C shared library libcmocka.so
[ 9%] Built target cmocka
Scanning dependencies of target assert_macro_test
[ 13%] Building C object example/CMakeFiles/assert_macro_test.dir/assert_macro.c.o
...
[ 95%] Building C object example/mock/uptime/CMakeFiles/uptime.dir/uptime.c.o
[100%] Linking C executable uptime
[100%] Built target uptime
sudo make install[  9%] Built target cmocka
...
[100%] Built target uptime
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/pkgconfig/cmocka.pc
-- Installing: /usr/local/lib/cmake/cmocka/cmocka-config.cmake
-- Installing: /usr/local/lib/cmake/cmocka/cmocka-config-version.cmake
-- Installing: /usr/local/include/cmocka.h
-- Installing: /usr/local/include/cmocka_pbc.h
-- Installing: /usr/local/lib/libcmocka.so.0.7.0
-- Installing: /usr/local/lib/libcmocka.so.0
-- Installing: /usr/local/lib/libcmocka.so

Unit Test Example

/*
* ---------------------------------------
* Copyright (c) Sebastian Günther 2021 |
* |
* devcon@admantium.com |
* |
* SPDX-License-Identifier: BSD-3-Clause |
* ---------------------------------------
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
static void test_integers(void** state) {
assert_int_equal(1,1);
}
int main(int argc, char* argv[]) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_integers),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
  • Always include all four libraries: <stdarg.h>, <stddef.h>, <setjmp.h>, <cmocka.h>
  • Define test cases as functions that receive an argument void** state
  • The test functions include different type of assert statements, shown here is assert_int_equal see the official documentation for the full list of asserts.
  • In the main function, add all defined test functions to the struct CMUnitTest tests[]

Running Tests

export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH}
clang -std=c18  -l cmocka simple.test.c -o tests.bin
$> ./test.bin[==========] Running 1 test(s).
[ RUN ] test_integers
[ OK ] test_integers
[==========] 1 test(s) run.
[ PASSED ] 1 test(s).

Testing a Pico Program

ShiftRegister Struct: Definition and Testing

  • Serial (SER): Set a single bit, low or high
  • Serial Clock (SRCLK): Send a clock signal that will write the active SER bit to the shift register
  • Register Clock (RCLK): Send a clock signal to copy the contents of the shift register into the storage register
typedef struct ShiftRegister
{
u_int8_t SERIAL_PIN;
u_int8_t SHIFT_REGISTER_CLOCK_PIN;
u_int8_t STORAGE_REGISTER_CLOCK_PIN;
} ShiftRegister;
void test_shift_register_config(void **state)
{
ShiftRegister reg = {14, 11, 12};
assert_int_equal(reg.SERIAL_PIN, 14);
assert_int_equal(reg.SHIFT_REGISTER_CLOCK_PIN, 11);
assert_int_equal(reg.STORAGE_REGISTER_CLOCK_PIN, 12);
}
Runing Tests
[==========] Running 1 test(s).
[ RUN ] test_shift_register_config
[ OK ] test_shift_register_config
[==========] 1 test(s) run.
[ PASSED ] 1 test(s).

Writing a single bit

typedef u_int8_t bitmask;typedef struct ShiftRegister;
{
bool serial_pin_state;
u_int8_t shift_register_state;
} ShiftRegister;
bool write_bit(ShiftRegister *reg, bool b,)
{
reg->serial_pin_state = b;
(b) ? (reg->register_state += 0b10) : (reg->register_state <<= 0b01);
return b;
}
void test_write_bit(void **state)
{
ShiftRegister reg = {14, 11, 12};
write_bit(1, &reg);
assert_int_equal(reg.serial_pin_state, 1);
write_bit(0, &reg);
assert_int_equal(reg.serial_pin_state, 0);
printf("Shift Register: %s\n", print_shift_register(&reg));
assert_memory_equal(print_shift_register(&reg), ®"01000000", 8);
}
Running Tests
[==========] Running 2 test(s).
[ RUN ] test_shift_register_config
[ OK ] test_shift_register_config
[ RUN ] test_write_bit
Shift Register: 01000000
[ OK ] test_write_bit
[==========] 2 test(s) run.
[ PASSED ] 2 test(s).

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store