在 C++ 中确保条件编译代码的单元测试

Unit test for ensuring conditionally compiled code in c++

这是我的代码中定义的标准 C++ ASSERT 宏 -

#ifndef DEBUG
#define ASSERT(n)
#else
#define ASSERT(n) \
if (!(n)){  \
    printf("%s - Failed ", #n); \
    printf("On %s ", __DATE__); \
    printf("At %s ", __TIME__); \
    printf("In File %s ", __FILE__); \
    printf("At Line %d\n", __LINE__); \
    exit(1);}
#endif

我想通过绑定单元测试来确保我的构建始终包含此代码。测试应检查是否未提供 #DEBUG 预处理器(即它是发布模式),单元测试中应用的条件检查应失败,ASSERT 宏失败并包含上面给出的消息。

是否有既定的方法来实现这一点?我正在使用 google 测试框架来实现这一点,但无法实现结果。测试失败并显示标准断言消息,而不是我尝试失败的自定义断言。 我的代码如下 -

TEST(VerifyNormalInitialization, VerifyAssert)
{
    static int index = 0;
    static int num = 4;
    ASSERT(index == num);
    EXPECT_FATAL_FAILURE(ASSERT(index == num),"Failed");
}

首先显而易见的是,当定义了 DEBUG 时,以下内容只会引发错误。

ASSERT(index == num);
ASSERT(index != num);

对于两种情况的单元测试:生产和开发,您需要两种方式都编译。

你可能会影响你自己 #define/#undef DEBUG

好的做法?我不知道;我不知道这是值得测试的东西。也许只是验证 ASSERT 在开发过程中处于活动状态。这是安装检查的内容。

考虑

EXPECT_FATAL_FAILURE(if (!(index == num)){ ... },"Failed");

这看起来像有效的 C++ 吗?不是。

考虑编写一个宏,将 #n__FILE__ 等传递给适当的函数。如果您坚持单独使用宏,那么它需要是单个表达式而不是语句,类似于:

#define STR2(x) #x
#define STR(x) STR2(x)

#define ASSERT(n)                                          \
(                                                          \
  fprintf(stderr,                                          \
          #n " - Failed on " __DATE__ " at " __TIME__      \
          " in file " __FILE__ " at line " STR(__LINE__)   \
         ),                                                \
  exit(EXIT_FAILURE)                                       \
)

这是使用 compile-time 字符串连接来准备整个字符串。此表达式中的所有内容都是字符串文字,并且 "hello""world" 等两个字符串文字被 pre-processor 连接为 "helloworld".

“字符串化”宏只是将整数 __LINE__ 转换为字符串文字。 Stringification - how does it work?

注意),是逗号运算符,用于允许在同一个表达式中调用两个函数。