I am trying to create a simple unit test library for my projects. I can get most things working, but now I am trying to add some functionality: printing the expressions/input.
It works if I pass arguments by actual value (1, 2.456, false), but if I pass a function argument I get the function string printed.
Here is my code explaining the problem I am not 100% sure what the STR(x) macro is doing, copied it from somewhere online...
The code actually works (the evaluation of LHS and RHS) just the printing does not, shown below.
#include <stdio.h>
#define STR(x) #x
#define TEST_COMPARE_EQ(TestName, LHS, RHS) \
do { \
if ((LHS) != (RHS)) { \
printf("[Test: %s] --- Failed at line %d in file %s\n", TestName, __LINE__, __FILE__); \
printf("\Got value %s\n", STR(LHS)); \
printf("\Expected value %s\n", STR(RHS)); \
} \
else { \
printf("[Test: %s] --- Passed\n", TestName); \
}\
} while (0)
// Calling code example
// This works, prints:
// Got value 123
// Expected value 124
TEST_COMPARE_EQ("PrintingWorks", 123, 124);
// This however does not work.
// It prints
// Got value my_fn_that_returns_false
// Expected value true
// How can I get it to print the return value of my_fn_that_returns_false, and not
// the actual function name?
TEST_COMPARE_EQ("PrintingDoesNotWork", my_fn_that_returns_false(), true);
CodePudding user response:
what the STR(x) macro is doing,
It takes the code as it is and adds "
in front and back. STR(anything)
is "anything"
, just like that.
How can I get it to print the return value
You have to print it.
printf("Got value %d\n", LHS);
No, there are no templates in C. It is hard to write type generic functions in C. You have to handle each possible type separately - like TEST_COMPARE_EQ_INT
TEST_COMPARE_EQ_FLOAT
etc. For inspiration, take a look at Unity C unit testing library.
Writing that in a type-generic way sounds like a nice challenge in C. It would look basically like the following:
void test_eq_int(int a, const char *astr, int b, const char *btr) {
if (a != b) {
printf("%s = %s -> %d != %s\n", astr, bstr, a, b);
}
}
void test_eq_long(....) { .... }
void test_eq_some_other_type(...) { .... }
// etc. for each possible type
#define TEST_COMPARE_EQ(msg, a, b) \
_Generic(a, \
int: test_eq_int, \
long: test_eq_long, \
/* etc. for each type */ \
)(msg, a, #a, b, #b);