Foo* bar(int const i)
{
assert(i != 0);
if (i == 0)
{
/*
* When asserts are disabled, this returns `NULL`.
*
* The code below can safely assume that `i != 0` --
* not just because there's an assert up there, but
* because this early return gracefully handles the
* case where `i` is 0 when asserts are disabled.
*/
return NULL;
}
// Do something with `i` here and return a non-`NULL` pointer.
}
6条答案
按热度按时间avwztpqn1#
也许只有我这么认为,但我认为如果你有Assert失败,你甚至不应该考虑更高级别的单元测试,直到你把它们修复。这个想法是Assert应该永远在任何情况下失败,包括单元测试,如果代码编写正确。至少我是这样写代码的。
oymdgrw72#
您可以测试Assert在您期望的时候中止(在错误的输入时)。
测试框架Google Test作为一个ASSERT_DEATH宏,它将测试程序在您期望的地方中止(如Assert)。
您也可以使用定义的NDEBUG(-DNDEBUG with gcc)进行编译,以禁用单元测试的Assert。
gfttwv5a3#
不,单元测试是你在开发过程中所做的。Assert是运行时构造。
根据我的经验,大多数情况下,Assert在生产中是关闭的。但你应该总是测试。
CppUnit是一个很好的测试框架。它是C++的nUnit家族的一部分。
omvjsjqw4#
Assert在任何情况下都不应该失败。如果它们在测试中失败,则表明存在逻辑错误。基本上,如果你的函数正在执行“assert(0)”而不是返回错误代码,那么这个函数应该重写。如果中止是期望的行为,那么exit()是合适的,而不是assert()。
如果Assert在测试期间失败,则代码出错,必须更改。代码“assert(x)”应该被解释为“程序的逻辑要求x为真。如果你有一个导致Assert失败的单元测试,那么这个语句显然是无效的,必须修改。
bihw5rsg5#
这听起来就像你的测试框架不是为了测试你的Assert而构建的。
使用一个将停止进程的Assert,您需要一些东西来监视您的执行状态。
boost-test如何执行此操作的示例:http://www.boost.org/doc/libs/1_34_0/libs/test/doc/components/prg_exec_monitor/index.html
我已经有一段时间没有写C或C++代码了,但是,我会从类似的技术开始。
fbcarpbf6#
假设你的代码准备好了优雅地处理那些Assert被关闭时会触发Assert的情况,并且你想对这些情况进行单元测试,确保这些情况确实被优雅地处理,一种方法是编译一个测试可执行文件,在相关的对象文件中禁用Assert。
例如,假设你在
Foo.c
中有这个函数:您想测试当用
0
调用时,bar()
是否实际返回NULL
。在makefile中,假设你有两个可执行文件:
${MAIN_EXE}
,你编写应用程序的常规可执行文件,以及你希望启用Foo.c
的Assert**的地方${TESTS_EXE}
,运行单元测试的可执行文件,您希望Foo.c
的Assert被禁用从
Foo.c
,您还可以生成 * 两个不同的对象文件 *:Foo.o
,assertsenabled的那个,要链接到${MAIN_EXE}
Foo_test.o
,assertsdisabled的,要链接到${TESTS_EXE}
现在,当运行测试可执行文件时,只会启用测试可执行文件的Assert,允许您像这样对
bar()
进行单元测试:当运行常规可执行文件时,
Foo.c
的Assert仍将正常启用,提醒您代码中的错误。