如何确保Boost.Test测试在预期失败场景下必现失败?
Boost.Test 强制验证测试失败的实现方案
需求背景
你需要在单个测试用例里,调用同一测试函数两次:
- 传入合法参数时,要求完全无失败
- 传入非法参数时,要求至少有一个断言失败,以此验证测试函数本身的有效性,避免出现“理应失败却始终通过”的bug
现有方案的问题
expected_failures装饰器:仅标记预期会有失败,但不会强制失败发生——如果测试意外通过,整个用例依然会被判定为通过,无法验证测试函数的有效性- 旧邮件列表方案:
BOOST_CHECK_PREDICATE( not( check_is_close ), (a)(b)(percent_tolerance(t)) ),既要求每个断言都失败(你只需要至少一个),还存在编译问题
可行解决方案
方案1:利用测试结果捕获机制
通过Boost.Test的test_case_scope捕获特定代码块的测试结果,然后强制验证该结果是否为失败:
#include <boost/test/unit_test.hpp> #include <boost/test/test_tools.hpp> void test_funct(double arg_a, double arg_b) { BOOST_CHECK_CLOSE(arg_a, 1.0, 0.1); BOOST_CHECK_CLOSE(arg_b, 1.0, 0.1); } BOOST_AUTO_TEST_CASE(test_validity) { // 合法参数调用:要求无失败 test_funct(1.0, 1.0); // 非法参数调用:捕获测试结果并强制验证失败 boost::unit_test::test_results call_results; { boost::unit_test::test_case_scope scope(call_results); test_funct(1.0, 2.0); } // 确保此次调用确实产生了失败 BOOST_CHECK_MESSAGE(!call_results.passed(), "测试函数在非法参数下未按预期失败,测试本身存在bug"); }
说明
test_case_scope会将代码块内的所有断言结果收集到call_results中- 通过
BOOST_CHECK_MESSAGE断言call_results.passed()为false,如果测试函数意外通过,这个断言会直接触发失败,明确提示测试本身有问题
方案2:手动统计失败次数
修改测试函数,让它返回断言失败的次数,直接验证次数是否符合预期:
#include <boost/test/unit_test.hpp> #include <boost/test/test_tools.hpp> int test_funct_count_failures(double arg_a, double arg_b) { int fail_count = 0; if (!BOOST_CHECK_CLOSE(arg_a, 1.0, 0.1)) fail_count++; if (!BOOST_CHECK_CLOSE(arg_b, 1.0, 0.1)) fail_count++; return fail_count; } BOOST_AUTO_TEST_CASE(test_validity) { // 合法参数:失败次数必须为0 BOOST_CHECK_EQUAL(test_funct_count_failures(1.0, 1.0), 0); // 非法参数:失败次数至少为1 BOOST_CHECK_GT(test_funct_count_failures(1.0, 2.0), 0); }
说明
- 测试函数返回失败的断言数量,逻辑直观易懂
- 用
BOOST_CHECK_EQUAL和BOOST_CHECK_GT直接验证两次调用的失败次数,完全满足你的需求
内容的提问来源于stack exchange,提问作者A_K
相关产品推荐
相关产品推荐

