我使用Boost Test框架对我的C++代码进行单元测试,并想知道是否可以测试函数是否会断言?是的,听起来有点奇怪,但请忍受我!我的许多函数在输入时检查输入参数,断言它们是否无效,并且测试它是有用的.例如:
void MyFunction(int param) { assert(param > 0); // param cannot be less than 1 ... }
我希望能够做到这样的事情:
BOOST_CHECK_ASSERT(MyFunction(0), true); BOOST_CHECK_ASSERT(MyFunction(-1), true); BOOST_CHECK_ASSERT(MyFunction(1), false); ...
你可以检查使用Boost测试抛出的异常,所以我想知道是否还有一些断言魔法......
遇到同样的问题,我挖掘了文档(和代码)并找到了一个"解决方案".
Boost UTF使用boost::execution_monitor
(in
).这旨在捕获测试执行期间可能发生的一切.当发现一个断言时,execution_monitor会拦截它并抛出boost::execution_exception
.因此,通过使用,BOOST_REQUIRE_THROW
您可以断言断言的失败.
所以:
#include#include // for execution_exception BOOST_AUTO_TEST_CASE(case_1) { BOOST_REQUIRE_THROW(function_w_failing_assert(), boost::execution_exception); }
应该做的伎俩.(这个对我有用.)
但是(或免责声明):
这个对我有用.也就是说,在Windows XP,MSVC 7.1上,提升1.41.0.它可能不适合您的设置或损坏.
这可能不是Boost Test的作者的意图.(虽然它似乎是execution_monitor的目的).
它将以同样的方式处理每种形式的致命错误.我可能是你的断言以外的东西都失败了.在这种情况下,您可能会错过ega内存损坏错误,和/或错过失败的失败断言.
它可能会破坏未来的升级版本.
我希望如果在Release配置中运行它会失败,因为断言将被禁用,断言设置为阻止的代码将运行.导致非常不确定的行为.
如果,在msvc的Release配置中,无论如何都会发生一些类似断言或其他致命错误,它将不会被捕获.(请参阅execution_monitor文档).
如果您使用assert或不使用取决于您.我喜欢他们.
看到:
http://www.boost.org/doc/libs/1_41_0/libs/test/doc/html/execution-monitor/reference.html#boost.execution_exception
执行监控用户指南.
另外,感谢Gennadiy Rozental(Boost测试的作者),如果你碰巧读到这个,那就太棒了!
我想检查两种错误:不变量和运行时错误.
不变量是永远都应该是真实的东西,无论如何.对于那些,我使用断言.像你这样的事情不应该传递给你我输出缓冲区的零指针.这是代码中的一个错误,简单明了.在调试版本中,它会断言并给我一个纠正它的机会.在零售版本中,它将导致访问冲突并生成小型转储(Windows,至少在我的代码中)或coredump(Mac/unix).有没有catch
我可以做有意义对付解引用一个零指针.在Windows上,catch (...)
可以抑制访问冲突,并且当用户已经非常可怕,可怕的错误时,会让用户产生一种错误的信心.
这就是为什么我开始相信这catch (...)
通常是C++中的代码气味的一个原因,也是我能够想到存在的唯一合理的地方是在生成核心转储并礼貌地退出应用程序之前main
(或WinMain
).
运行时错误类似于"由于权限我无法写入此文件"或"由于磁盘已满而无法写入此文件".对于这些类型的错误,抛出异常是有道理的,因为用户可以对其执行某些操作,例如更改目录的权限,删除某些文件或选择备用位置来保存文件.这些运行时错误可由用户纠正.用户无法仅通过程序员纠正违反不变量的情况.(有时两者是相同的,但通常不是.)
单元测试应强制代码抛出代码可能生成的运行时错误异常.您可能还希望强制协作者的异常,以确保您的被测系统是异常安全的.
但是,我不相信尝试强制您的代码使用单元测试来对抗不变量是有价值的.
我不这么认为.您总是可以编写自己的断言,它会抛出异常,然后对该异常使用BOOST_CHECK_NOTHROW().