Google Test 死亡测试

Google Test 死亡测试

[TOC]
本文简短介绍Google Test 死亡测试.

官网翻译整理.

概述

死亡测试(Death Test),即程序因为各种原因挂掉的测试,只测试挂掉这一种现象,并且捕捉挂掉原因.

例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TEST(MyDeathTest, Foo) {
// This death test uses a compound statement.
ASSERT_DEATH({
int n = 5;
Foo(&n);
}, "Error on line .* of Foo()");
}

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

TEST(MyDeathTest, KillProcess) {
EXPECT_EXIT(KillProcess(), testing::KilledBySignal(SIGKILL),
"Sending myself unblockable signal");
}

死亡测试的线程安全

生成新进程,在新进程中进行死亡测试(进程间不共享资源,保证安全性).

生成进程取决于平台,通过编译选项--gtest_death_test_style,指定到::testing::GTEST_FLAG(death_test_style)。具体生成进程命令如下:

  • POSIX 系统, fork() (clone() Linux 的话)
    • --gtest_death_test_style值为fast,立即执行执行死亡测试的语句.此方式为默认.
    • --gtest_death_test_style值为threadsafe,安装测试代码设定的那样运行,目的是在线程安全性与测试执行效率间取得平衡.
  • Windows系统 CreateProcess()API,只有threadsafe模式.

引入GTEST_FLAG_SET的原因是考虑线程安全. 有可能fork出来的线程(threads started by statically-initialized modules)无法被释放. Google Test 采用了三种策略应对这个问题.

  • 当死亡测试遇到多线程环境就会WARNING.
  • DeathTest结尾的test suite会在其他test之前进行.
  • 在Linux上使用clone取代fork.

在死亡测试的 statement 里进行多线程是没问题的,因为死亡测试是在新进程里的.

GTEST_FLAG_SET的设置方式非常灵活,可以设置全局的也可以随用随设置.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
GTEST_FLAG_SET(death_test_style, "fast");
return RUN_ALL_TESTS();
}

TEST(MyDeathTest, TestOne) {
GTEST_FLAG_SET(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(), "");
}

注意:子线程里释放内存/修改变量的操作(in-memory side effect)可能不会被父线程看到,因此如果 statement 跑在子线程里要遵守如下:

  1. 死亡测试里不要释放资源.
  2. 或者在父线程里再释放一遍.
  3. 或者程序里不要用heap checker.

死亡断言(Death Assertions)

Fatal Nonfatal 说明
EXPECT_DEATH(statement,matcher) ASSERT_DEATH(statement,matcher) 验证statement因为非0 exit status 而产生的 stderr 是否匹配 matcher .
EXPECT_DEATH_IF_SUPPORTED(statement,matcher) ASSERT_DEATH_IF_SUPPORTED(statement,matcher) 如果系统支持死亡测试,则等同于EXPECT_DEATH,否则等于空.
EXPECT_EXIT(statement,predicate,matcher) ASSERT_EXIT(statement,predicate,matcher) EXPECT_DEATH基础上加入谓词函数定义statementmatcher的匹配过程.

matcher的三种形式:

谓词函数predicate为一个入参int( exit status code),返回值为bool的函数对象.Google Test 提供了2种供一般使用.

1
2
3
4
5
6
// 匹配 exit status code.
::testing::ExitedWithCode(exit_code);

// 匹配信号signal
// Windows不可用
::testing::KilledBySignal(signal_number);
作者

cx

发布于

2021-12-10

更新于

2022-07-16

许可协议