What is the inverse of EXPECT_DEATH?

对着背影说爱祢 提交于 2021-01-29 07:54:32

问题


With google tests, let's assume the following code

#include <iostream>

using namespace std;
using MyFunc = void (*)(void);

void foo_robust(MyFunc f)   { if(f != nullptr) (*f)(); }
void foo_not_robust(MyFunc f)   { (*f)(); }
void print(void)     { cout << "hello world" << endl; }

int main()
{
    foo(&print); //works
    foo(nullptr); //runtime error ?
    return 0;
}

When using google test,

I can do:

TEST(TestAssertDeath, Death)
{
    EXPECT_DEATH(foo(&print)); //will return FAILED, because does not die.
    EXPECT_DEATH(foo(nullptr)); //will return FAILED if foo robust, OK otherwise (UB: it might even return FAILED)
}

I want to do:

TEST(TestAssertDeath, No_Death)
{
    EXPECT_NO_DEATH(foo(&print)); //will return OK, because does not die.
    EXPECT_NO_DEATH(foo(nullptr)); // will return OK, if foo is robust, FAILED or DEATH otherwise (UB: it might even return OK)
}

Is there any google macro that does "EXPECT_NO_DEATH" 's job? I tried EXPECT_NO_FATAL_FAILURE but it crashes as if I put nothing. I want to do:

TEST(TestAssertDeath, No_Death)
{
    EXPECT_NO_FATAL_FAILURE(foo(&print)); //will return OK, because does not die.
    EXPECT_NO_FATAL_FAILURE(foo(nullptr)); // will crash (UB: might even return OK)
}

But I don't want the test campaing to be stopped.

Google test gives me currently the following error.

[ RUN      ] MyClass.MyUnitTestA
[      OK  ]
[ RUN      ] MyClass.MyUnitTestB
[      OK  ]
[ RUN      ] MyClass.MyUnitTestC
mingw32-make[3]: *** [CMakeFiles/myproject-coverage] Error -1073741819
mingw32-make[2]: *** [CMakeFiles/myproject-coverage.dir/all] Error 2
mingw32-make[1]: *** [CMakeFiles/myproject-coverage.dir/rule] Error 2
mingw32-make: *** [myproject-coverage] Error 2

Because this stops the other tests from running, I would like something as the following if the code is not robust

[ RUN      ] MyClass.MyUnitTestA
[      OK  ]
[ RUN      ] MyClass.MyUnitTestB
[      OK  ]
[ RUN      ] MyClass.MyUnitTestC
[  DEATH   ] or [  FAILED  ]
[ RUN      ] MyClass.MyUnitTestD
[      OK  ]

and this if the code is robust:

[ RUN      ] MyClass.MyUnitTestA
[      OK  ]
[ RUN      ] MyClass.MyUnitTestB
[      OK  ]
[ RUN      ] MyClass.MyUnitTestC
[      OK  ]
[ RUN      ] MyClass.MyUnitTestD
[      OK  ]

Important note: I know that the line foo_not_robust(nullptr) is UB and will not ends up in a crash automatically, but if it does, I want this line to be skipped and marked as failed.


回答1:


To make unit tests robust against crashing you could try to run each test in a child process, with a parent process that monitors the child process for success, failure or crash.

But there is an easy way, in fact you can do something as EXPECT_NO_DEATH

From google test doc:

TEST(MyDeathTest, NormalExit) { EXPECT_EXIT(NormalExit(), ::testing::ExitedWithCode(0), "Success"); }

You can hack it by using two statements (statement1,statement2) with statement1 = statement and statement2 = exit(0)

It gives the two following custom macros:

# define EXPECT_CRASH(statement) \
    EXPECT_EXIT((statement,exit(0)),::testing::KilledBySignal(SIGSEGV),".*")
# define EXPECT_NO_CRASH(statement) \
   EXPECT_EXIT((statement,exit(0)),::testing::ExitedWithCode(0),".*")

EXPECT_CRASH() is equivalent to EXPECT_DEATH()

EXPECT_NO_CRASH() is equivalent the requested EXPECT_NO_DEATH()

Note that ::testing::KilledBySignal(signal_number) is not available on Windows. What you could do as a workaround for Windows is just defining:

# define EXPECT_CRASH(statement) \
    EXPECT_DEATH(statement,".*")

gives the following message:

[ RUN      ] MyClass.MyUnitTestA
[      OK  ]
[ RUN      ] MyClass.MyUnitTestB
[      OK  ]
[ RUN      ] MyClass.MyUnitTestC
Death test: (foo(),exit(0))
    Result: died but not with expected exit code:
            Exited with exit status -1073741819
Actual msg:
[  DEATH   ]
[ RUN      ] MyClass.MyUnitTestD
[      OK  ]


来源:https://stackoverflow.com/questions/57312559/what-is-the-inverse-of-expect-death

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!