2016-08-30 81 views
6

我正在使用gtest为异常处理代码编写一些单元测试。举一个简单的例子,让我们说,我想我的程序abort任何未处理的异常,所以我创建了以下测试:写入死亡测试来验证std :: set_terminate行为

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

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

我希望它可以成功,因为abort应在程序中调用。但是,我的实际结果是:

error: Death test: throw std::runtime_error("terminate")

Result: threw an exception.
Error msg:

[ DEATH ]
[ DEATH ] main.cpp(122):: Caught std::exception-derived exception escaping the death test statement. Exception message: terminate

[ DEATH ]

我认为gtest的异常处理程序正在进行中。我尝试使用GTEST_CATCH_EXCEPTIONS环境变量和--gtest_catch_exceptions=0命令行标志禁用它们,如the advanced guide中所述,但我得到了相同的结果。

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

回答

5

Am I doing something wrong, or is "death by exception" not something gtest can test for?

你在做什么是错的,因为“例外死”是不是GTEST可以测试。

EXPECT_DEATH(statement, regex); 

验证statement调用abortexit并且使输出匹配 regex。声明throw std::runtime_error("terminate")不会呼叫 abortexit,这可以从捕捉程序中的任何异常并让它继续进行的可能性中看出。 如果没有发现异常,则运行时库将调用terminate,以某种方式结束程序。但是这个结果不是由任何throw声明决定的。

documentation of death-tests, 特别是:

...any test that checks that a program terminates (except by throwing an exception) in an expected fashion is also a death test.

Note that if a piece of code throws an exception, we don't consider it "death" for the purpose of death tests, as the caller of the code could catch the exception and avoid the crash. If you want to verify exceptions thrown by your code, see Exception Assertions.

和:

Note that a death test only cares about three things:

  1. does statement abort or exit the process? ...

我很欣赏你在这里可以oversimplfying你真正的问题,但你 几乎需要测试未处理的异常会导致terminate 被调用,或者terminate将调用操作终止处理程序,除非它是您的艰巨任务是测试您的编译器和标准库的执行情况 。也许更多的真正问题应该是播出 ?

后来

my problem with this is my program doesn't (or shouldn't) carry on. It should abort via the termination handler.

它不应该,但每个文档的期望,你的程序应该 不携带由EXPECT_DEATH任何throw声明没有进行测试,因为没有throw声明终止程序。如果有的话仅仅是如果, 已经设置的处理程序,以std::terminate()通话有你 期望的结果

What I really want to test is that the behavior of my set_terminate handler is correct.

set_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. 
+0

我真正要测试的是我的'set_terminate'处理程序的行为是正确的,而且我认为它应该是被调用的。在真正的程序中,它在最终调用'abort'之前做了几件事(产生时间戳/栈跟踪)。 –

+0

“,这可以从捕捉程序中的任何异常并让它继续进行”......我的问题是我的程序不(不应该)继续进行。它应该通过终止处理程序“中止”。 –

+0

@NicolasHolthaus在那里更新。 –