EXPECT_DEATH的逆是什么?

时间:2019-08-01 15:38:14

标签: c++ unit-testing googletest

对于Google测试,我们假设以下代码

#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;
}

使用Google测试时,

我可以做到:

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

我想做:

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

是否有执行“ EXPECT_NO_DEATH”的工作的Google宏? 我尝试了EXPECT_NO_FATAL_FAILURE,但是它崩溃了,好像我什么都没放。 我想做:

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

但是我不希望测试野营停止。

Google测试当前给我以下错误。

[ 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

因为这会停止其他测试的运行,所以如果代码不够健壮,我想做以下事情

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

,如果代码很健壮,还可以这样做:

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

重要说明::我知道foo_not_robust(nullptr)行是UB,不会自动以崩溃结束,但是如果确实如此,我希望跳过这一行并将其标记为失败

1 个答案:

答案 0 :(得分:1)

要使单元测试更可靠地防止崩溃,您可以尝试在子进程中运行每个测试,并使用父进程监视子进程的成功,失败或崩溃。

但是有一种简单的方法,实际上您可以做一些EXPECT_NO_DEATH

来自Google测试文档:

  

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

您可以使用两个带有(statement1,statement2)statement1 = statement的语句statement2 = exit(0)来破解它

它提供了以下两个自定义宏:

# 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()等效于EXPECT_DEATH()

EXPECT_NO_CRASH()等同于请求的EXPECT_NO_DEATH()

请注意,::testing::KilledBySignal(signal_number)在Windows上不可用。 作为Windows的解决方法,您可以做的只是定义:

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

给出以下消息:

[ 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  ]