写死亡测试来验证std :: set_terminate行为

时间:2016-08-30 18:57:27

标签: c++ c++11 exception exception-handling googletest

我正在使用gtest为异常处理代码编写一些单元测试。举一个简单的例子,让我说我希望我的程序在任何未处理的异常上abort,所以我创建了以下测试:

TEST_F(myFixture, myTest)
{
    std::set_terminate([](){std::abort(); });

    EXPECT_DEATH(throw std::runtime_error("terminate"), ".*");
}

我希望这会成功,因为应该在程序上调用abort。但是,我的实际结果是:

  

错误:死亡测试:抛出std :: runtime_error("终止")

     

结果:抛出异常。
  错误消息:

     

[死亡]
  [DEATH] main.cpp(122)::抓住std :: exception-derived异常转义   死亡测试声明。异常消息:终止

     

[死亡]

我认为gtest的异常处理程序正在阻碍。我尝试使用GTEST_CATCH_EXCEPTIONS环境变量以及the advanced guide中提到的--gtest_catch_exceptions=0命令行标记来禁用它们,但我得到了相同的结果。

我做错了什么,或者是"异常死亡"不是gtest可以测试的东西吗?

1 个答案:

答案 0 :(得分:6)

  

我做错了什么,或者是"异常死亡"不是gtest可以测试的东西吗?

你做的是错的,因为"异常死亡"不是gtest可以测试的东西。

EXPECT_DEATH(statement, regex);

验证statement调用abortexit并导致输出匹配 regex。声明throw std::runtime_error("terminate")不会致电 abortexit,可以从程序中捕获任何异常并让它继续存在的可能性中看出。 如果未捕获异常,则运行时库将调用terminate,以某种方式结束程序。但是这个结果并不是由任何throw声明决定的。

参见documentation of death-tests, 特别是:

  

...检查程序终止的任何测试(除了抛出异常)   以预期的方式也是一种死亡测试。

     

请注意,如果一段代码抛出异常,我们就不会考虑它" death"   为了死亡测试的目的,因为代码的调用者可以捕获   例外并避免崩溃。如果您想验证您的异常抛出的异常   代码,请参阅异常断言。

  

请注意,死亡测试只涉及三件事:

     
      
  1. 语句是否中止或退出流程?   ...
  2.   

我感谢你,但是你可能会过度强调你的真实问题 几乎不需要测试未处理的异常会导致terminate 被呼叫,或terminate将呼叫有效终止 - 处理程序,除非你是测试执行的艰巨任务 你的编译器和标准库。也许更多的是真正的问题 播出?

<强>后来

  

我的问题是我的程序没有(或者不应该继续)。   它应该通过终止处理程序中止。

它应该,但根据文档,期望您的程序应该 EXPECT_DEATH 未对任何 throw 语句进行进行测试,因为没有throw语句终止程序。

  

我真正想要测试的是我的set_terminate处理程序的行为   是对的。

set_terminate处理程序的行为是正确的,如果只有, 设置了该处理程序后,对std::terminate()的调用会产生结果 期望。此问题独立于任何throw语句和 你可以测试它:

#include <iostream>
#include <gtest/gtest.h>
#include <exception>


TEST(the_end, is_nigh)
{
    std::set_terminate([](){std::cout << "Goodbye cruel world\n", std::abort(); });

    EXPECT_DEATH(std::terminate(), ".*");
}
int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

产生:

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from the_end
[ RUN      ] the_end.is_nigh
Goodbye cruel world
[       OK ] the_end.is_nigh (172 ms)
[----------] 1 test from the_end (172 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (172 ms total)
[  PASSED  ] 1 test.