gtest死亡测试

1、简介

  死亡测试的“死亡”指的是程序的崩溃。通常在测试过程中,我们需要考虑各种各样的输入,有的输入可能直接导致程序崩溃,这时我们就需要检查程序是否按照预期的方式挂掉,这也就是所谓的“死亡测试”。gtest的死亡测试能做到在一个安全的环境下执行崩溃的测试案例,同时又对崩溃结果进行验证。

2、相关的宏

  ASSERT_DEATH(statement, regex`); EXPECT_DEATH(statement, regex`); 语句因给定错误而崩溃

  ASSERT_EXIT(statement, predicate, regex`); EXPECT_EXIT(statement, predicate, regex`); 语句以给定的错误退出,其退出代码与谓词匹配
  有一些异常只在Debug下抛出,因此还提供了*_DEBUG_DEATH,用来处理Debug和Realease下的不同。

3、*_DEATH(statement, regex`)

  statement:被测试的代码语句
  regex:一个正则表达式,用来匹配异常时在stderr中输出的内容

注意:编写死亡测试案例时,TEST的第一个参数,即testcase_name,请使用DeathTest后缀。原因是gtest会优先运行死亡测试案例,应该是为线程安全考虑。

4、*_EXIT(statement, predicate, regex`)

  statement:被测试的代码语句
  predicate :必须是一个委托,接收int型参数,并返回bool。只有当返回值为true时,死亡测试案例才算通过。
  regex:一个正则表达式,用来匹配异常时在stderr中输出的内容

4.1 常用的predicate

  testing::ExitedWithCode(exit_code):    如果程序正常退出并且退出码与exit_code相同则返回 true
  testing::KilledBySignal(signal_number):    // Windows下不支持:如果程序被signal_number信号kill的话就返回true

注意:*_DEATH其实是对*_EXIT进行的一次包装,*_DEATH的predicate判断进程是否以非0退出码退出或被一个信号杀死。

示例:EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");

5、*_DEBUG_DEATH

5.1 定义

#ifdef NDEBUG

#define EXPECT_DEBUG_DEATH(statement, regex) \
  do { statement; } while (false)

#define ASSERT_DEBUG_DEATH(statement, regex) \
  do { statement; } while (false)

#else

#define EXPECT_DEBUG_DEATH(statement, regex) \
  EXPECT_DEATH(statement, regex)

#define ASSERT_DEBUG_DEATH(statement, regex) \
  ASSERT_DEATH(statement, regex)

#endif // NDEBUG for EXPECT_DEBUG_DEATH

  在Debug版和Release版本下, *_DEBUG_DEATH的定义不一样。因为很多异常只会在Debug版本下抛出,而在Realease版本下不会抛出,所以针对Debug和Release分别做了不同的处理。

5.2 gtest自带的例子

int DieInDebugElse12(int* sideeffect) {
  if (sideeffect) *sideeffect = 12;
  #ifndef NDEBUG
  GTEST_LOG_(FATAL, "debug death inside DieInDebugElse12()");
  #endif // NDEBUG
  return 12;
}

TEST(TestCase, TestDieOr12WorksInDgbAndOpt)
{
  int sideeffect = 0;
  // Only asserts in dbg.
  EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death");

  #ifdef NDEBUG
  // opt-mode has sideeffect visible.
  EXPECT_EQ(12, sideeffect);
  #else
  // dbg-mode no visible sideeffect.
  EXPECT_EQ(0, sideeffect);
  #endif
}

6、正则表达式

  在Windows系统中,gtest的死亡测试中使用的是gtest自己实现的简单的正则表达式语法。 相比POSIX风格,gtest的简单正则表达式少了很多内容,比如 ("x|y"), ("(xy)"), ("[xy]") 和("x{5,7}")都不支持。
gtest定义了2个宏,用来表示当前系统支持哪套正则表达式风格:
  POSIX风格:GTEST_USES_POSIX_RE = 1
  Simple风格:GTEST_USES_SIMPLE_RE=1

6.1 简单正则表达式支持的内容

匹配任何文字字符c
\\d   匹配任何十进制数字
\\D   匹配任何不是十进制数字的字符
\\f   匹配项\f
\\n   匹配项 \n
\\r   匹配项 \r
\\s   匹配任何ASCII空格,包括 \n
\\S   匹配任何非空白字符
\\t   匹配项\t
\\v   匹配项\v
\\w   匹配任何字母、_或十进制数字
\\W   匹配任何不匹配\\w的字符
\\c   匹配任何标点符号文本字符c
.    匹配字符除 \n外
A?    匹配A中0个或1个
A*    匹配A中0个或多个
A+    匹配A中一个或多个
^    匹配字符串的开头(不是每行的开头)
$    匹配字符串的结尾(不是每行的结尾)
xy    匹配跟y的x

7、死亡测试运行方式

1)fast方式(默认的方式)
  testing::FLAGS_gtest_death_test_style = "fast";

2)threadsafe方式
  testing::FLAGS_gtest_death_test_style = "threadsafe";
可以在 main() 里为所有的死亡测试设置测试形式,也可以为某次测试单独设置。Google Test会在每次测试之前保存这个标记并在测试完成后恢复。

7.1 示例

TEST(MyDeathTest, TestOne) {
  testing::FLAGS_gtest_death_test_style = "threadsafe";
  // 该测试案例运行在threadsafe方式
  ASSERT_DEATH(ThisShouldDie(), "");
}

TEST(MyDeathTest, TestTwo) {
  // 该测试案例运行在fast默认方式
  ASSERT_DEATH(ThisShouldDie(), "");
}

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  testing::FLAGS_gtest_death_test_style = "fast";
  return RUN_ALL_TESTS();
}

8、注意事项

1)不要在死亡测试里释放内存
2)在父进程里再次释放内存
3)不要在程序中使用内存堆检查

猜你喜欢

转载自www.cnblogs.com/Sheenagh/p/12215408.html