I'm new to unit testing and I'm wondering about best practices and how these are applied using Unity / Ceedling. I'm especially wondering how to avoid code duplication when testing multiple function inputs, but at the same time keeping it clear what is tested. Does it make sense to use loops or should every test be called separately? Is it normal to define each test with a different input as a separate test case? Does Ceedling offer some frame work for testing a function with multiple inputs?

An example: I have a function LoadR1IntoR2 which copies the content of the register specified by R1 into the register specified by R2. R1 and R2 can be seen as enumerations which specify the registers A..E, H and L, and are defined by u8_Input1: Byte 6..7 -> don't care; Byte 3..5 -> specify R2; Byte 0..2 -> specify R1. ps_GPRegs contains the registers which values should be manipulated. Here's the function declaration:

b LoadR1IntoR2(GeneralPurposeRegs *ps_GPRegs, u8 u8_Input1, u8 u8_Input2, u8 u8_Input3);

R1 and R2 can both take 7 different values (0..5, 7; 6 is undefined) which means there are at least 49 different combinations to test.

In my current solution I have defined one general test macro for this scenario and call it for every possible combination of R1 and R2:

#define TEST_LOAD_R1_INTO_R2(target, source, value) \
/* .. macro stuff and test assertions etc .. */

void test_LoadR1IntoR2(void) 
{
    /* .. initialisation .. */
    TEST_LOAD_R1_INTO_R2(A, A, 99)
    TEST_LOAD_R1_INTO_R2(A, B, 100)
    TEST_LOAD_R1_INTO_R2(A, C, 101)
    TEST_LOAD_R1_INTO_R2(A, D, 102)
    TEST_LOAD_R1_INTO_R2(A, E, 103)
    TEST_LOAD_R1_INTO_R2(A, L, 104)
    TEST_LOAD_R1_INTO_R2(A, H, 105)
    TEST_LOAD_R1_INTO_R2(B, A, 106)
    /* .. and so on .. */

}

I also thought about defining a new function:

void loadR1IntoR2_test(GeneralPurposeRegs *ps_GPRegs, enum_R e_R1, enum_R e_R2, u8 u8_TestValue);

and calling this function either in a loop within test_LoadR1IntoR2 for using just one test case or defining 49 test cases and calling loadR1IntoR2_test with different inputs.

1

There are 1 best solutions below

1
On

You can just use loop:

for (int i = 0; i < 107; i++)
{
    TEST_LOAD_R1_INTO_R2(A, A, i)
}