C ++中表达性断言失败消息

时间:2015-06-18 10:15:24

标签: c++ unit-testing assertions verbosity

单元测试框架通常提供非常好的断言失败消息(我正在使用gtest)来描述特定测试的预期值和实际值。此外,您知道函数调用的起源,因为您正在测试类的接口。

相比之下,assert,当在实现中用作健全性检查时,提供了一些但更加神秘的信息。例如,我正在研究的那个。 。

Assertion failed: (latency > std::chrono::milliseconds(0)), function setLatency, file /path/to/my.cpp line 71

所以我知道哪个断言失败了,但我不知道导致它失败的值是什么,更重要的是,我不知道调用setLatency的问题函数。

一个简单的解决方案通常是放到调试器,但在这个实例中我不能这样做。是否有可能从类的实现中获得更具描述性的断言消息?我怎样才能做到这一点?如果有必要,我不介意使用第三方库。

2 个答案:

答案 0 :(得分:2)

此问题的常见解决方案是创建断言宏。有关示例,请参阅this question。答案中宏的最终形式如下:

#define dbgassert(EX,...) \
  (void)((EX) || (realdbgassert (#EX, __FILE__, __LINE__, ## __VA_ARGS__),0))

在您的情况下,realdbgassert将是一个函数,它将任何相关信息输出到stderr或其他输出控制台,然后调用断言函数本身。根据您需要的信息量,您还可以执行stack dump,或记录可帮助您确定问题的任何其他相关信息。但是,它可以像传递printf-esque格式字符串和相关参数值一样简单。

请注意,如果编译器不支持可变参数宏,则可以创建采用特定数量参数的宏。这稍微麻烦一些,但如果你的编译器缺乏支持,那就是一个选项,例如:

#define dbgassert0(EX) \ ...
#define dbgassert1(EX,p0) \ ...
#define dbgassert2(EX,p0,p1) \ ...

答案 1 :(得分:0)

我不确定这是否是您正在寻找的,但您可以将任何您喜欢的消息附加到"断言失败:..."做这样的事情的消息:

assert(1==1 && "This is always true");
assert(1==0 && "This always fails");

当然,您可以修改字符串以包含值或更多信息。