3

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.

Community
  • 1
  • 1
Peregrin
  • 424
  • 4
  • 11
  • `EXPECT_DEATH(obj->getIndex(4))` ? Maybe the title for your question should be changed to "How to not terminate in Google test when assert() unexpectedly triggers?" or something like that. – coyotte508 May 28 '16 at 14:28
  • @coyotte508 that's the point. EXPECT_DEATH and ASSERT_DEATH expect assert to trigger. I don't expect it to trigger but in case it triggers (due to some changes in code) I the program to continue with other tests without termination. I expected something like ASSERT_NOT_DEATH to exist but couldn't find it. – Peregrin May 28 '16 at 18:36

4 Answers4

4

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.

admo
  • 51
  • 1
  • 6
Antonio Pérez
  • 6,702
  • 4
  • 36
  • 61
2

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

  • thanks, this is a good advice. But I'm developing very complex system and I don't know at the moment what would be the best way to handle wrong input. It might throw exception or something else but the easiest for me at the moment just to put an assert so that wrong input is handled at least for now – Peregrin May 28 '16 at 21:07
  • I understand your point; however, I have two reasons for verifying assert statements: (1) My previous company uses test cases to help document code. Thus, writing a test case that verifies an assert failure is one way of formalizing that "the input may not be null". The test case isn't a substitute for other documentation; but, I have found it a helpful addition. (2) It is much easier to find a bug when it trips a documented assert than when it wreaks havoc later in the program. The couple of minutes to add a test case can save an hour of debugging later when the code is used incorrectly. – Zack Jul 24 '16 at 18:56
0

If assert triggers (fails) you get "nice output" (or a crash or whatever assert does in your environment). If assert does not trigger then nothing happens and execution continues. What more do you need to know?

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • description clearly says what I need. I don't want it to crash so that other tests can be executed. – Peregrin May 28 '16 at 14:16
  • @Peregrin but if the assertion does not trigger it simply does nothing (doesn't crash). Program execution just continues after the assert. So why do you need to do anything special? You can just continue with whatever the program is supposed to do if the assertion doesn't trigger. What's so difficult to understand about that? – Jesper Juhl May 28 '16 at 14:20
0

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

DiB
  • 554
  • 5
  • 19