Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

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:

  • 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 useful in

  • 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

  • No labels