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

1. gtest死亡测试

死亡测试中常见的宏如下

Fatal assertion Nonfatal assertion Verifies
ASSERT_DEATH(statement, regex`); EXPECT_DEATH(statement, regex`); statement crashes with the given error
ASSERT_EXIT(statement, predicate, regex`); EXPECT_EXIT(statement, predicate, regex`); statement exits with the given error and its exit code matches predicate

由于有些异常只在Debug下抛出,因此还提供了*_DEBUG_DEATH,用来处理Debug和Realease下的不同。

1.2 *_DEATH(statement, regex`)

  1. statement是被测试的代码语句
  2. regex是一个正则表达式,用来匹配异常时在stderr中输出的内容
void Foo()
{int *pInt = 0;*pInt = 42 ;
}TEST(FooDeathTest, Demo)
{EXPECT_DEATH(Foo(), "");
}

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

1.3 *_EXIT(statement, predicate, regex`)

  1. statement是被测试的代码语句
  2. predicate 在这里必须是一个委托,接收int型参数,并返回bool。只有当返回值为true时,死亡测试案例才算通过。gtest提供了一些常用的predicate:

testing::ExitedWithCode(exit_code)。如果程序正常退出并且退出码与exit_code相同则返回 true

testing::KilledBySignal(signal_number)  // Windows下不支持。如果程序被signal_number信号kill的话就返回true

regex是一个正则表达式,用来匹配异常时在stderr中输出的内容。这里, 要说明的是,*_DEATH其实是对*_EXIT进行的一次包装,*_DEATH的predicate判断进程是否以非0退出码退出或被一个信号杀死。

TEST(ExitDeathTest, Demo)
{EXPECT_EXIT(_exit(1),  testing::ExitedWithCode(1),  "");
}

1.4 *_DEBUG_DEATH

#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分别做了不同的处理。看gtest里自带的例子就明白了:

int DieInDebugElse12(int* sideeffect) {if (sideeffect) *sideeffect = 12;
#ifndef NDEBUGGTEST_LOG_(FATAL, "debug death inside DieInDebugElse12()");
#endif  // NDEBUGreturn 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
}

2. 关于正则表达式

在POSIX系统(Linux, Cygwin, 和 Mac)中,gtest的死亡测试中使用的是POSIX风格的正则表达式,想了解POSIX风格表达式可参考:

1. POSIX extended regular expression

2. Wikipedia entry.

在Windows系统中,gtest的死亡测试中使用的是gtest自己实现的简单的正则表达式语法。 相比POSIX风格,gtest的简单正则表达式少了很多内容,比如 ("x|y"), ("(xy)"), ("[xy]") 和("x{5,7}")都不支持。

下面是简单正则表达式支持的一些内容:

matches any literal character c
\\d matches any decimal digit
\\D matches any character that's not a decimal digit
\\f matches \f
\\n matches \n
\\r matches \r
\\s matches any ASCII whitespace, including \n
\\S matches any character that's not a whitespace
\\t matches \t
\\v matches \v
\\w matches any letter, _, or decimal digit
\\W matches any character that \\w doesn't match
\\c matches any literal character c, which must be a punctuation
. matches any single character except \n
A? matches 0 or 1 occurrences of A
A* matches 0 or many occurrences of A
A+ matches 1 or many occurrences of A
^ matches the beginning of a string (not that of each line)
$ matches the end of a string (not that of each line)
xy matches x followed by y

gtest定义两个宏,用来表示当前系统支持哪套正则表达式风格:

1. POSIX风格:GTEST_USES_POSIX_RE = 1

2. Simple风格:GTEST_USES_SIMPLE_RE=1

4. 死亡测试运行方式

1. fast方式(默认的方式)

testing::FLAGS_gtest_death_test_style = "fast";

2. threadsafe方式

testing::FLAGS_gtest_death_test_style = "threadsafe";

你可以在 main() 里为所有的死亡测试设置测试形式,也可以为某次测试单独设置。Google Test会在每次测试之前保存这个标记并在测试完成后恢复,所以你不需要去管这部分工作 。如:

TEST(MyDeathTest, TestOne) {testing::FLAGS_gtest_death_test_style = "threadsafe";// This test is run in the "threadsafe" style:ASSERT_DEATH(ThisShouldDie(), "");
}TEST(MyDeathTest, TestTwo) {// This test is run in the "fast" style:ASSERT_DEATH(ThisShouldDie(), "");
}int main(int argc, char** argv) {testing::InitGoogleTest(&argc, argv);testing::FLAGS_gtest_death_test_style = "fast";return RUN_ALL_TESTS();
}

八、注意事项

1. 不要在死亡测试里释放内存。

2. 在父进程里再次释放内存。

3. 不要在程序中使用内存堆检查。

总结

关于死亡测试,gtest官方的文档已经很详细了,同时在源码中也有大量的示例。如想了解更多的请参考官方的文档,或是直接看gtest源码。

简单来说,通过*_DEATH(statement, regex`)和*_EXIT(statement, predicate, regex`),我们可以非常方便的编写导致崩溃的测试案例,并且在不影响其他案例执行的情况下,对崩溃案例的结果进行检查。

死亡测试 - GoogleTest(五)相关推荐

  1. 玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试

    一.前言 "死亡测试"名字比较恐怖,这里的"死亡"指的的是程序的崩溃.通常在测试过程中,我们需要考虑各种各样的输入,有的输入可能直接导致程序崩溃,这时我们就需要 ...

  2. Google Test(GTest)使用方法和源码解析——死亡测试技术分析和应用

    死亡测试是为了判断一段逻辑是否会导致进程退出而设计的.这种场景并不常见,但是GTest依然为我们设计了这个功能.我们先看下其应用实例.(转载请指明出于breaksoftware的csdn博客) 死亡测 ...

  3. 全国大学生软件测试大赛Web应用测试(五)Jmeter性能测试环境配置

    全国大学生软件测试大赛Web应用测试(五)Jmeter性能测试环境配置 web应用测试环境配置所需资料链接 JMeter客户端下载 Badboy客户端下载 web应用测试环境配置所需资料链接 JMet ...

  4. 慕课软件质量保证与测试(第五章.课后作业)

    慕课金陵科技学院.软件质量保证与测试.第五章.软件测试过程.课后作业 0 目录 5 软件测试过程 5.7 课后作业 5.7.1 课堂重点 5.7.2 测试与作业 6 下一章 0 目录 5 软件测试过程 ...

  5. STM32L051测试 (五、串口测试 — 与Enocean模块通讯问题)

    STM32L051测试 第五课,串口的使用 .... by 矜辰所致 ..添加目录栏目 2021/9/30 ..调整文章格式,增加串口接收卡死处理说明 2022/7/18 目录 前言 一.串口接收处理 ...

  6. 暗月渗透测试项目-五(上)

    暗月渗透测试项目五 准备工作 环境搭建 使用的是暗月提供的环境 直接虚拟机运行即可 设置网络环境 网卡配置的时候为了方便直接使用的是暗月的vm19的网卡配置的内网环境 环境搭建完成 如果使用的Mac的 ...

  7. 【转】请尊重测试:测试从业五年有感

    从数学专业毕业,到微软,到360,转眼快五年,人每次按年去回忆事情的时候,总会不禁的感慨,感慨人生的无奈,感慨世界的变迁,至少感慨时间的流逝,文雅的说法,就是江湖夜雨十年灯. 然而,it这个世界里,变 ...

  8. 使用python进行渗透测试_利用Python进行Web渗透测试(五):剖析HTTP请求

    本篇概要URL的结构 HTTP头域 HTTP状态码 一个完整的HTTPget请求 在上一篇我们简单介绍了HTTP协议的概念和知识,本篇我们来详细剖析一下HTTP的请求,将这两篇综合起来,我们就对HTT ...

  9. ESP32 测试(五): Light-sleep 模式下的电流功耗测试及特性(使用 Wi-Fi)

    一. 测试目的 经常会有开发者提出基于 ESP32 Light-sleep 模式下的电流功耗问题,本文将测试在连接 Wi-Fi 的情况下 Light-sleep 模式下的 ESP32 的电流功耗. 二 ...

  10. MOS管怎么测试好坏-如何测试有五种诀窍-KIA MOS管

    MOS管是金属-氧化物-半导体场效应晶体管,或称是金属-绝缘体-半导体.MOS管的source和drain是可以对调的,他们都是在P型backgate中形成的N型区.在多数情况下,这个两个区是一样的, ...

最新文章

  1. input自适应_一种Dynamic ReLU:自适应参数化ReLU(调参记录26)Cifar10~95.92%
  2. Leetcode-937-Reorder Log Files-(Easy)
  3. 聊聊spring tx的EnableTransactionManagement
  4. Maven搭建SpringMVC+Mybatis项目详解【转】
  5. 插入数据并返回插入数据ID
  6. Word 2013 无法撤销操作的错误
  7. cad.net cad启动慢? cad2008启动慢? cad启动延迟? cad卡住? cad98%卡? 默认打印机!!
  8. qq音乐网络异常获取音乐失败_QQ音乐无法播放_为什么qq音乐总是提示歌曲无效或网络连接失败?...
  9. 华为p4支持鸿蒙功能吗_只要华为鸿蒙系统能支持三个APP,我就愿意支持!
  10. 夸克浏览器网页版入口网址分享
  11. Pandas写入Excel文件如何避免覆盖已有Sheet
  12. 依据MPU6050角速度原始数据的计步算法
  13. EasyExcel的导入和导出
  14. idea中添加类、方法注释,快捷键设置
  15. 汽车启动档位,份4个
  16. 广告系统架构:要啥自行车!
  17. 汇编语言课程视频目录 【B站】
  18. css第二课:外部样式link和import的运用及行内样式的介绍
  19. 如何处理具有指数增长或衰减特征的数据
  20. 37来电号码归属地的显示

热门文章

  1. 对于谷歌搜索的一些基本语法整理
  2. 使用piranha搭建高可用LVS集群
  3. 关于短除法求两个数的最小公倍数的公式的解释
  4. vscode风格化设置
  5. C2-关于VCF文件合并的几种方法
  6. postgresql日常运维:Postgresql运维的自动驾驶
  7. html导航条背景颜色代码,div+css实现鼠标经过背景高亮的导航菜单代码
  8. 斯芬克怎么样 谁说我没有担心
  9. appcan ajax mysql_AppCan里面的Ajax通信实例
  10. 【考研英语语法】十大词性