C语言单元测试宏如何打印作为参数的函数调用返回值
问题原因
你用到的STR(x)是C预处理器的字符串化运算符,只会在预处理阶段把宏参数的字面代码直接转换为C字符串,完全不会执行任何运行时求值逻辑。所以当你传入函数调用作为参数时,它直接把my_fn_that_returns_false()这段代码转成了字符串输出,和运行时的函数返回值没有任何关联。
你原本的测试逻辑中(LHS) != (RHS)判断是正常求值的,但是打印逻辑只输出了表达式的字面字符串,没有输出运行时结果,这就是问题的核心原因。
修复方案
我们可以在宏中先对LHS、RHS做一次求值并存入临时变量,既可以避免重复执行表达式带来的副作用(比如函数内部修改全局变量,多次执行结果不一致),也能拿到实际的运行时结果用于打印。
如果你的测试场景以整型(布尔、int、枚举等可隐式转为int的类型)为主,可以用以下修改后的实现:
#include <stdio.h> #define STR(x) #x #define TEST_COMPARE_EQ(TestName, LHS, RHS) \ do { \ // 先求值存入临时变量,GCC/Clang原生支持typeof,C23标准已正式纳入该关键字 typeof(LHS) lhs_val = (LHS); \ typeof(RHS) rhs_val = (RHS); \ if (lhs_val != rhs_val) { \ printf("[Test: %s] --- Failed at line %d in file %s\n", TestName, __LINE__, __FILE__); \ // 可根据需要选择是否保留原始表达式打印 printf("Got value: %d (expression: %s)\n", (int)lhs_val, STR(LHS)); \ printf("Expected value: %d (expression: %s)\n", (int)rhs_val, STR(RHS)); \ } \ else { \ printf("[Test: %s] --- Passed\n", TestName); \ }\ } while (0)
如果需要支持浮点、字符串等更多类型,可以结合C11的_Generic关键字自动匹配对应类型的打印格式符。
效果示例
对于你给出的测试用例:
TEST_COMPARE_EQ("PrintingDoesNotWork", my_fn_that_returns_false(), true);
假设my_fn_that_returns_false()返回0、true定义为1,失败时的打印结果为:
[Test: PrintingDoesNotWork] --- Failed at line xx in file test.c Got value: 0 (expression: my_fn_that_returns_false()) Expected value: 1 (expression: true)
内容的提问来源于stack exchange,提问作者user2840470
相关产品推荐
相关产品推荐

