I am using CMocka to write some unit tests. Some of my tests loop though a list of cases which are stored in a struct to avoid repetition:
typedef struct {
char* test_arg;
int expected;
} TestCase;
const static TestCase cases[] = {
{"1", 1}, {"2", 1},
{0}
};
void test_the_cases(void **state)
{
for (const TestCase* case = cases; case->test_arg != NULL; case++)
{
int got_result = atoi(case->test_arg);
// Check the result matches
// If this fails, this line is where the assertion is
assert_int_equal(c->expected, got_result);
}
}
This does work:
[==========] tests: Running 1 test(s).
[ RUN ] test_the_cases
[ ERROR ] --- 0x1 != 0x2
[ LINE ] --- <file>.c:64: error: Failure!
[ FAILED ] test_the_cases
[==========] tests: 1 test(s) run.
[ PASSED ] 0 test(s).
[ FAILED ] tests: 1 test(s), listed below:
[ FAILED ] test_the_cases
1 FAILED TEST(S)
However, the assertion is simply at line 64 (assert_int_equal(...)
), and in this case, the failed case is clear. But, it isn't always - perhaps the failure is a number that doesn't appear directly in the case, or is shared between cases, meaning you can't tell from the ERROR
and LINE
which TestCase
failed. I don't really want to printf()
every case, or there'll be thousands of lines of spam in the tests, but I also don't want to have to re-run tests with debugging levels raised to see what failed.
With Boost Test, I could use a message or context (docs) to do this and print a handy message on failure (including nice things like RAII scope, but it's C++, so that's why). In Cmocka, I have the state
parameter to store messages in if I need, however, I can't see how I can hook into an assertion failure to print that message to the user.
It occurs that if you know if tests failed during teardown, you could implement a stack of strings with state
, push and pop during execution and print them if failure occured, but as it is, I can't see that the teardown callback has any idea of the test pass/fail status.
Is this possible in CMocka?