0

I'm implementing a test library and I want to be able to print the test functions, which fail. Therefore I need a way to get the name of the failing function. I know there are predefined identifiers like __func__ and __FUNCTION__, but they only give me the name of the last executed function. I also don't want to use those identifiers inside the unit test functions, but in the procedure, which runs all the tests.

I posted an example, which uses an imaginary function called function_name. Is there any macro or something else available for this purpose?

/** Description
 *      This function calls a number of unit tests and print the results.
 *      Please note the imaginary function 'function_name'.
 * 
 *  Parameters:
 *      tests: Function pointers to unit tests
 *      number_tests: The number of tests to run
 */
void run_tests(unit_test* tests, unsigned int number_tests) {
    int number_passed = 0;

    for (unsigned int i = 0; i < number_tests; i++) {
        // Execute the unit test and get the result
        test_result result = (*tests[i])();

        if (result == TEST_PASSED)
            number_passed++;
        else
            printf("Test %s failed!\n", function_name(*tests[i]));
    }

    printf("%d/%d passed tests, %d failed tests\n", number_passed,
        number_tests, number_tests - number_passed);
}
3
  • 1
    Fyi, when you said, "they only give me the name of the last executed function" you probably meant "they only give me the name current function". You're already reaping the functions by address into tests (somewhere not shown). One alternative if to reap them into an array of struct func { int (*pfn)(); const char *fname; } and stringize the name whilst your loading up tests, reporting that instead. Commented Feb 4, 2022 at 12:19
  • It would seem that your test variable should simply be a struct indeed. The solution to the problem should be where you set up the unit_test array. Otherwise since you have a unison API where everything returns a test_result, why can't that contain a copy of the __func__ string? Commented Feb 4, 2022 at 12:24
  • I don't understand how function_name(*tests[i]) makes sense however. Commented Feb 4, 2022 at 12:25

1 Answer 1

4

Since you're using C, a good solution seems to lie in the use of the preprocessor, and in the use of a richer structure for the unit_test type. That is: instead of simply having a function pointer, it would contain also the function name, like:

struct _unit_test {
   int (*func)();
   char* func_name;
};
typedef struct _unit_test unit_test;

A macro like this would help it be populated

#define ptr_name(x) {x, #x}

And the initialization of the tests array could be

unit_tests tests[] = {ptr_name(func1), ptr_name(func2)};

You would have to change the following line of your code

test_result result = (*tests[i])();

to

test_result result = tests[i].func();

And the failed result line to

printf("Test %s failed!\n", tests[i].func_name);
Sign up to request clarification or add additional context in comments.

1 Comment

Cool, thank you. Using a macro to automatically transform the variable name of the input to a string (char pointer) helped me!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.