简体   繁体   English

当 assert() 意外触发时,如何抑制 Google 测试中的终止?

[英]How to suppress termination in Google test when assert() unexpectedly triggers?

Here it's discussed how to catch failing assert, eg you setup your fixture so that assert() fails and you see nice output. 这里讨论了如何捕获失败的断言,例如,您设置您的装置,以便 assert() 失败并且您会看到不错的输出。 But what I need is the opposite.但我需要的是相反的。 I want to test that assert() succeeds.我想测试 assert() 是否成功。 But in case it fails I want to have nice output.但如果它失败了,我想有很好的输出。 At that point it just terminates when it snags on assert().那时它只是在它在 assert() 上卡住时终止。

#define LIMIT 5

struct Obj {
    int getIndex(int index) {
        assert(index < LIMIT);
        // do stuff;
    }
}

Obj obj;

TEST(Fails_whenOutOfRange) {
    ASSERT_DEATH(obj->getIndex(6), "");
}

TEST(Succeeds_whenInRange) {
    obj->getIndex(4);
}

Above is contrived example.以上是人为的例子。 I want second test not to terminate in case it fails, for example if I set LIMIT to 3. After all, ASSERT_DEATH suppresses somehow termination when assert() fails.我希望第二个测试在失败时不终止,例如,如果我将 LIMIT 设置为 3。毕竟,当 assert() 失败时,ASSERT_DEATH 会以某种方式抑制终止。

You should try using the command line option --gtest_break_on_failure您应该尝试使用命令行选项--gtest_break_on_failure

It is meant to run tests within a debugger, so you get a breakpoint upon test failure.它旨在在调试器中运行测试,因此您会在测试失败时获得断点。 If you don't use a debugger you'll just get a SEGFAULT and execution will stop.如果您不使用调试器,您只会得到一个 SEGFAULT 并且执行将停止。

The following is just my opinion, but it seems for me that you are either testing a wrong thing, or using a wrong tool.以下只是我的意见,但在我看来,您要么测试了错误的东西,要么使用了错误的工具。

Assert (C assert() ) is not for verifying input, it is for catching impossible situations. Assert (C assert() ) 不是用于验证输入,而是用于捕获不可能的情况。 It will disappear from release code, for example, so you can't rely on it.例如,它将从发布代码中消失,因此您不能依赖它。

What you should test is your function specification rather than implementation .您应该测试的是您的功能规范而不是实现 And you should decide, what is your specification for invalid input values:您应该决定,您对无效输入值的规范是什么:

  • Undefined behavior, so assert is fine, but you can't test it with unit-test, because undefined behavior is, well , undefined.未定义行为,所以assert是好的,但你不能用单元测试进行测试,因为不确定的行为,那么,不确定的。

  • Defined behavior.定义的行为。 Then you should be consistent regardless of NDEBUG presence.那么无论是否存在NDEBUG您都应该保持一致。 And throwing exception, in my opinion, is the right thing to do here, instead of calling std::abort , which is almost useless for user (can't be intercepted and processed properly).在我看来,抛出异常是正确的做法,而不是调用std::abort ,这对用户几乎没有用(不能被正确拦截和处理)。

If assert triggers (fails) you get "nice output" (or a crash or whatever assert does in your environment).如果assert触发(失败),您会得到“不错的输出”(或崩溃或断言在您的环境中所做的任何事情)。 If assert does not trigger then nothing happens and execution continues.如果assert没有触发,那么什么都不会发生并且继续执行。 What more do you need to know?你还需要知道什么?

This (hack) adds a EXPECT_NODEATH macro to Google Test.这个(hack)向谷歌测试添加了一个EXPECT_NODEATH宏。 It is the "opposite" of EXPECT_DEATH in that it will pass if the statement does not assert, abort, or otherwise fail.它与EXPECT_DEATH的“相反”在于,如果语句没有断言、中止或以其他方式失败,它将通过。

The general idea was simple, but I did not take the time to make the error messages any nicer.总体思路很简单,但我没有花时间使错误消息更好看。 I tried to leave Google Test as untouched as possible and just piggy-back on what is already there.我试图让谷歌测试尽可能保持原样,只是捎带上已经存在的东西。 You should be able to include this without any side effects to the rest of Google Test您应该能够将其包含在内,而不会对 Google 测试的其余部分产生任何副作用

For your case:对于您的情况:

TEST(Succeeds_whenInRange) {
    EXPECT_NODEATH(obj->getIndex(4), "");
}

GTestNoDeath.h GTestNoDeath.h

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM