Peregrin
Peregrin

Reputation: 436

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

Here it's discussed how to catch failing assert, e.g. you setup your fixture so that assert() fails and you see nice output. But what I need is the opposite. I want to test that assert() succeeds. But in case it fails I want to have nice output. At that point it just terminates when it snags on 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.

Upvotes: 3

Views: 5370

Answers (3)

Antonio P&#233;rez
Antonio P&#233;rez

Reputation: 6962

You should try using the command line option --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.

Upvotes: 4

DiB
DiB

Reputation: 613

This (hack) adds a EXPECT_NODEATH macro to Google Test. It is the "opposite" of EXPECT_DEATH in that it will pass if the statement does not assert, abort, or otherwise fail.

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

For your case:

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

GTestNoDeath.h

Upvotes: 0

user2512323
user2512323

Reputation:

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

  • Defined behavior. Then you should be consistent regardless of NDEBUG presence. 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).

Upvotes: 2

Related Questions