Google Test(gtest)新手入门
gtest),也称为Google C++ Testing Framework,是一个由Google开发的开源C++测试框架,提供了多种工具来支持C++代码的单元测试。提供了多种断言方法,可以用于测试函数、代码片段的预期行为。支持自动化测试,可以方便编写测试用例,并自动运行和输出结果。支持死亡测试(Death Test),测试代码在极端或异常条件下的行为表现。提供测试夹具(Test Fixture,
简介
Google Test(
gtest
),也称为Google C++ Testing Framework,是一个由Google开发的开源C++测试框架,提供了多种工具来支持C++代码的单元测试。主要功能包括:
- 提供了多种断言方法,可以用于测试函数、代码片段的预期行为。
- 支持自动化测试,可以方便编写测试用例,并自动运行和输出结果。
- 支持死亡测试(Death Test),测试代码在极端或异常条件下的行为表现。
- 提供测试夹具(Test Fixture,一种用于编写可重复执行的测试用例的机制),使得测试用例便于重用。
- 易于组织测试用例,通过测试套件集中管理。
- 提供参数化测试、类型参数化测试等功能。
- 与其他Google测试框架集成,如Google Mock(
gmock
,用于测试的模拟对象),可以用来测试代码依赖。- 支持多平台使用,包括Linux、Windows、Mac等。
一、安装
官方源码:GitHub - google/googletest: GoogleTest - Google Testing and Mocking Framework
我安装在linux上,版本是v1.13.0
,官方已明确要求使用的C++标准至少是C14版本。详细的安装过程已在googletest-main/googletest/README.md
中说明,如果嫌阅读英文麻烦可以执行以下命令:
git clone https://github.com/google/googletest.git -b v1.13.0
cd googletest # Main directory of the cloned repository.
cmake .. -DBUILD_GMOCK=OFF
make
sudo make install # Install in /usr/local/ by default
为找到自己需要的帮助文档,可以先看看googletest-main/docs/index.md
。
# GoogleTest User's Guide
## Welcome to GoogleTest!
GoogleTest is Google's C++ testing and mocking framework. This user's guide has
the following contents:
* [GoogleTest Primer](primer.md) - Teaches you how to write simple tests using
GoogleTest. Read this first if you are new to GoogleTest.
* [GoogleTest Advanced](advanced.md) - Read this when you've finished the
Primer and want to utilize GoogleTest to its full potential.
* [GoogleTest Samples](samples.md) - Describes some GoogleTest samples.
* [GoogleTest FAQ](faq.md) - Have a question? Want some tips? Check here
first.
* [Mocking for Dummies](gmock_for_dummies.md) - Teaches you how to create mock
objects and use them in tests.
* [Mocking Cookbook](gmock_cook_book.md) - Includes tips and approaches to
common mocking use cases.
* [Mocking Cheat Sheet](gmock_cheat_sheet.md) - A handy reference for
matchers, actions, invariants, and more.
* [Mocking FAQ](gmock_faq.md) - Contains answers to some mocking-specific
questions.
新手入门可阅读primer.md
,高级功能可阅读advanced.md
。
二、基本概念
1、怎样才算是好的测试程序?
- 测试应是独立的和可重复的。
- 测试应易于组织,并反映被测试代码的结构。
gtest
会将共享数据的测试分组到同一测试套件中。 - 测试应该是可移植的和可重用的。
- 当测试失败时,应该提供尽可能多的关于这个问题的信息。
gtest
不会在第一次测试失败时停止。相反,它只停止当前的测试,并继续执行下一个测试。这样就能在一个运行周期中检测并修复多个错误。 - 测试框架应该将测试编写者从繁复工作中解放出来,并让他们专注于测试内容。
gtest
会自动检测所有的测试套件,而不需要用户枚举所有的测试来运行它们。 - 测试应该很快。对于共享的数据,只需要构造、销毁一次就跨测试复用共享资源,无需使测试相互依赖。
2、命名规则
在gtest
中,一个测试用例用宏TEST()
表示,简称为测试。接下来的解释中,请不要混淆。
3、断言
gtest
中的测试用例都是通过使用断言来验证被测代码的行为。断言是检查条件是否为真的语句。断言的结果可以是成功、非致命失败或致命失败。如果发生致命失败,则中止当前函数;否则程序将正常继续运行。
TEST(TestSuiteName, TestName) {
//... test body ...
}
使用TEST()
宏来定义一个测试,TEST()
是一个没有返回值的宏函数。函数体中除了C++语句外,还需要添加断言。测试的结果就由断言的结果来决定。TEST()
包含两个参数,第一个参数是测试套件的名称,第二个参数是测试套件中的测试的名称。这两个名称都必须是有效的C++标识符,并且它们不应该包含任何下划线(_)。
gtest
按测试套件将测试结果进行分组,因此逻辑相关的测试应该在同一个测试套件中;也就是说,它们TEST()
定义中,第一个参数应该是相同的。
int Factorial(int n); // 返回n的阶乘
// 测试0的阶乘,属于FactorialTest测试套件
TEST(FactorialTest, HandlesZeroInput) {
EXPECT_EQ(Factorial(0), 1);
}
// 测试正数的阶乘,属于FactorialTest测试套件
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(Factorial(1), 1);
EXPECT_EQ(Factorial(2), 2);
EXPECT_EQ(Factorial(3), 6);
EXPECT_EQ(Factorial(8), 40320);
}
断言类似于宏函数。当断言失败时,gtest
将打印断言的源文件和行号位置,以及一条失败消息。你还可以提供一个自定义的失败消息,将它附加到gtest
的输出信息中。如下:
// 一切能通过ostream输出的内容都能通过这两个宏输出
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
ASSERT_*
这类断言会在失败时产生致命错误,并中止当前函数。EXPECT_*
断言则生成非致命错误,它不会中止当前函数。通常首选EXPECT_*
,因为它们允许在一个测试中报告多个错误信息。但是,如果出现失败后继续运行没有意义时,你应该使用ASSERT_*
。
关于断言更详细的说明可以参考googletest-main/docs/reference/assertions.md
。
4、测试夹具
测试是最小的组成单位。一个测试套件包含一个或多个测试,用来划分单独的功能。一个测试程序中包含多个测试套件。当一个测试套件中的多个测试需要共享公共对象和子例程时,可以将它们放到一个测试夹具(Test Fixture)中。
测试夹具(Test Fixture)是一种用于编写可重复执行的测试用例的机制。它可以在多个测试用例中重复使用,主要有以下特点:
- 测试夹具类中包含多个测试用例。
- 提供预置条件(SetUp)和收尾清理(TearDown)代码,为多个测试用例初始化环境和清理环境。
- 每个测试用例可以关注不同的功能点或输入,并验证输出。
- 测试夹具封装了准备工作,使测试用例更简洁。
- 同一个测试夹具可以重复用于不同的测试用例集。
可以这样创建一个夹具:
- 继承
::testing::Test
,并将其成员声明为protected
,方便它的子类访问。 - 在类中声明你需要使用的对象。
- 有必要的话,创建
SetUp()
函数用于初始化对象,相当于类的构造函数。 - 有必要的话,创建
TearDown()
函数用于回收对象,相当于类的析构函数。 - 使用
TEST_F()
宏函数来声明夹具,与TEST()
类似,只不过第一个参数必须为夹具类名,第二个参数则为测试名。
如,创建一个队列的测试夹具:
template <typename E> // E is the element type.
class Queue {
public:
Queue();
void Enqueue(const E& element);
E* Dequeue(); // Returns NULL if the queue is empty.
size_t size() const;
...
};
class QueueTest : public ::testing::Test {
protected:
void SetUp() override {
// q0_ remains empty
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// void TearDown() override {}
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
}
TEST_F(QueueTest, IsEmptyInitially) {
EXPECT_EQ(q0_.size(), 0);
}
TEST_F(QueueTest, DequeueWorks) {
int* n = q0_.Dequeue();
EXPECT_EQ(n, nullptr);
n = q1_.Dequeue();
ASSERT_NE(n, nullptr);
EXPECT_EQ(*n, 1);
EXPECT_EQ(q1_.size(), 0);
delete n;
n = q2_.Dequeue();
ASSERT_NE(n, nullptr);
EXPECT_EQ(*n, 2);
EXPECT_EQ(q2_.size(), 1);
delete n;
}
三、运行样例
1、示例路径
有哪些示例,示例演示的功能,已经在googletest-main/docs/samples.md
中进行了说明。代码存放在googletest-main/googletest/samples
下。但是示例不能直接运行,需要建立cmake工程进行编译。
2、创建cmake工程
在sample
目录下新建case1
目录,将sample1_unittest.cc
、sample1.cc
、sample1.h
拷贝至该目录。其中sample1.h
、sample1.c
是用户功能模块,sample1_unittest.cc
是单元测试模块。main
函数则可以引用现有的src/gtest_main.c
文件。添加CMakeLists.txt
后就创建了sample1
的cmake工程。
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
# 工程名
project(gtest_sample)
# 配置编译选项
set(CMAKE_CXX_COMPILE_FLAGS "std=c++14")
# 头文件路径
include_directories(
/usr/local/include/gtest
${CMAKE_CURRENT_SOURCE_DIR}/../../include/gtest
)
# 生成可执行程序的文件,使用通配符指定
file(GLOB CPP_FILES
${CMAKE_CURRENT_SOURCE_DIR}/*.c*
${CMAKE_CURRENT_SOURCE_DIR}/../../src/gtest_main.c*
)
add_executable(${PROJECT_NAME} ${CPP_FILES})
# 依赖库列表
target_link_libraries(${PROJECT_NAME}
gtest
gtest_main
pthread
)
-
Note
- file()支持引用通配符,能包含所有需要的.cc文件;
- 按说明文档指示,编译标准至少支持c14;
- 依赖的库中需要添加pthread
- 如果不想重写main函数,可以链接gtest_main,使用官方的main函数;
3、运行结果
cd case1
cmake .
make
./gtest_sample
运行结果会展示运行了几个测试套件、耗时、以及结果。
四、高级功能
这里仅介绍部分高级功能概念,至于如何使用,还是得参考googletest-main/docs/advanced.md
。
- 更丰富的断言
使用谓词形式的断言、使用带返回值的断言、浮点断言、字符串断言、gmock使用。 - 死亡测试(Death Test)
一种特殊的单元测试技术,用于检测代码在极端或异常条件下的行为表现。通过故意传入非法或极端输入,使被测代码产生崩溃或异常。验证代码在这种情况下是否如预期般崩溃。 如果没有崩溃,则测试失败。 - 记录额外信息
能生成xml、json等格式的报告。 - 类型测试
可以先定义测试逻辑,然后再用不同的类型列表来实例化… - …
更多推荐
所有评论(0)