gpt4 book ai didi

c++ - 编写死亡测试以验证 std::set_terminate 行为

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:30:16 24 4
gpt4 key购买 nike

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

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 可以测试的?

最佳答案

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

你做的是错误的,因为“异常死亡”不是 gtest 可以测试的。

EXPECT_DEATH(statement, regex);

验证 statement 调用 abortexit 并导致输出匹配正则表达式。语句 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? ...

我很感激你在这里可能过度简化了你的真正问题,但你几乎不需要测试未处理的异常是否会导致 terminate被调用,或者 terminate 将调用操作终止-处理程序,除非您有艰巨的职责来测试你的编译器和标准库。也许更多的真正的问题应该播出?

稍后

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

它应该,但根据文档,您的程序应该not carry on 未通过 EXPECT_DEATH 任何 throw statement 测试,因为没有throw 语句终止程序。

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

您的 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.

关于c++ - 编写死亡测试以验证 std::set_terminate 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39235131/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com