Unit testing plan
Requirements of the unit testing system:
Easily create unit tests for each function
Easily create mocks of functions that are not under test
Test what functions are being called and their arguments in the function under test
Test "contacts" between systems/boards. I.e in a BPS unit test we mock Controls to ensure BPS acts in a specific way when Controls sends us an input
System can override macros
We use macro defines to define system parameters (like how many battery modules we have.
Our system should be configurable and shouldn't break if i change one of the defines
ie if I change NUM_BATTERY_MODULES to 31 instead of 32, BPS shouldn't try and get a 32nd module and be confused
Many systems need ways to test sensor readings and filter correctness, so we need a way to inject artificial noise into whatever we’re reading
Implementation:
Cmock + Unity
Cmock offers a simple way to create mocks by autogenerating mocks based on function call syntax
Unity does the actual comparisons for the unit tests
Problems:
We are doing a lot of RTOS stuff, which we'd need to mock
Cmock's autogenerated mocks require looking at the function and seeing what is called instead of looking at the I/O of the function. Meaning when implementation changes the unit test will be invalid
RTOS support:
We can have some helper functions in our unit testing code to blackbox all RTOS calls and make them return true or success so we can test logic without RTOS easily
BSP testing:
We can (reasonably) say that the STM32 HAL functions work, so we can ensure in our BSP_I2C_Write() function, we're calling HAL_I2C_Write() with the proper function arguments
Test cases where queue's are full or empty
Trace macros
Let's see if we can use trace macros to test if we enter specific states in our function
Use the macro that is called when we block on a mutex indefinitely to see if we ever infinite block in an interrupt
Driver testing:
If we make our drivers use RTOS functions, we can pass in fake data structures (could be queues) and see if it either adds to the output data structure properly, and it tests for blocking access
Same logic as BSP testing where we assume BSP calls work fine, and ensure that my function calls the correct BSP function with the correct arguments the correct amount of times
Dependency injection is a pretty common tactic, but is mostly used in C++
Task testing:
this one kinda sucks
For basic logic tests we have all RTOS functions return success or nothing, just to test if our logic without RTOS is correct
Ie BPS trips when I pass in an array full of voltages that 69420 mV
Expansions:
CI/CD will let us run regression tests, so if at one point we change something it will test logical correctness for every function.
When running integration tests (beyond unit tests) we can use Unity as a method to test situations we put our system in
Welcome to the University Wiki Service! Please use your IID (yourEID@eid.utexas.edu) when prompted for your email address during login or click here to enter your EID. If you are experiencing any issues loading content on pages, please try these steps to clear your browser cache.