参考博客:
Advanced googletest Topics | GoogleTest
玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制 - CoderZh - 博客园 (cnblogs.com)
前言:
本文主要是在cpp文件里使用了官网提供的示例代码来熟悉GTest的三种事件机制(TestCase级别、TestSuite级别、全局),为了方便简洁,源码中没有定义对应的头文件,只有cpp文件。
1 TestCase级别
1.1使用方法
- 编写一个类FooTest,继承testing::Test
- 在FooTest里实现SetUp()和TearDown()方法,SetUp方法会在每个TestCase执行开始前执行;TearDown方法会在每个TestCase执行完成后执行
- 编写TestCase时,要将第一个参数TestFixtureName(TEST_F函数)/TestSuiteName(TEST函数)要写成FooTest
2 TestSuite级别
出现的原因: GTest为每一个test创建一个fixture对象,来让每一个test独立并且易于调试。但是,有时候test使用的资源设置起来代价很高,这使得每个test创建一个fixture对象的模型代价非常高。
适用场景: 如果test并不会去改变资源,那么多个test共享一份资源也就没有什么问题。
2.1 使用方法
- 在测试固件类中,将一些成员变量声明为静态的,这样就可以保留共享的资源
- 在测试固件类外,定义那些静态成员变量, 可选地给它们初始值。
- 在同一个测试固件类中:定义一个
static void SetUpTestSuite()
函数,用来配置共享的资源; 定义一个static void TearDownTestSuite()
函数用来释放这些资源。在运行这个测试固件类中的第一个测试用例之前,GTest会自动调用SetUpTestSuite()
,在运行完测试固件类中最后一个测试用例之后,GTest会自动调用TearDownTestSuite()
3 Program级别
3.1使用方法
- 编写一个类Environment,继承
testing::Environment
- 在Environment里重写
SetUp()
和TearDown()
方法,SetUp方法会在所有的TestCase执行开始前执行;TearDown方法会在所有TestCase执行完成后执行 - 实例化一个Environment对象,并调用
AddGlobalTestEnvironment(Environment* env)
方法;注意AddGlobalTestEnvironment(Environment* env)
的调用要在RUN_ALL_TESTS()
前
3.2 注意事项
- 允许注册多个环境对象(我理解的是允许声明多个类继承
testing::Environment
,然后注册不同类的多个环境对象吧,同一个环境类声明多个对象没什么意义吧?)。 在这个套件中,它们的SetUp()将按注册的顺序调用,而TearDown()将按相反的顺序调用 - googletest拥有注册的环境对象的所有权。因此,请不要自行删除
4 运行实例
源代码
该项目由test.pp、testAddIntegers.cpp、testSubIntegers.cpp构成
test.cpp:
#include <gtest/gtest.h>
class Environment : public ::testing::Environment {
public:
~Environment() override {}
// Override this to define how to set up the environment.
void SetUp() override {
printf("Environment类:全局级别SetUp函数执行!\n");
}
// Override this to define how to tear down the environment.
void TearDown() override {
printf("Environment类:全局级别TearDown函数执行!\n");
}
};
class EnvironmentNew : public ::testing::Environment {
public:
~EnvironmentNew() override {}
// Override this to define how to set up the environment.
void SetUp() override {
printf("EnvironmentNew类:全局级别SetUp函数执行!\n");
}
// Override this to define how to tear down the environment.
void TearDown() override {
printf("EnvironmentNew类:全局级别TearDown函数执行!\n");
}
};
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
// 定义了两个环境对象,以达到添加两种全局事件的目的
Environment* global;
global = new Environment();
//注意要定义指针对象,不能定义类对象然后参数取地址(这样做只定义一个类对象不影响运行,但是定义两个环境对象时运行结果会报堆栈的错误)
AddGlobalTestEnvironment(global);
EnvironmentNew* globalNew;
globalNew = new EnvironmentNew();
AddGlobalTestEnvironment(globalNew);
return RUN_ALL_TESTS();
}
testAddIntegers.cpp:
#include "stdio.h"
#include "gtest/gtest.h"
namespace myAdd {
namespace projectAdd {
namespace {
int add(int a, int b)
{
return a + b;
}
// The fixture for testing class Foo.
class AddIntegers : public ::testing::Test {
protected:
// You can remove any or all of the following functions if their bodies would
// be empty.
static void SetUpTestSuite() {
// Avoid reallocating static objects if called in subclasses of FooTest.
printf("AddIntegers类TestSuite级别SetUp函数执行!\n");
}
// Per-test-suite tear-down.
// Called after the last test in this test suite.
// Can be omitted if not needed.
static void TearDownTestSuite() {
printf("AddIntegers类TestSuite级别TearDown函数执行!\n");
}
AddIntegers() {
// You can do set-up work for each test here.
printf("AddIntegers类构造函数执行!\n");
}
~AddIntegers() override {
// You can do clean-up work that doesn't throw exceptions here.
printf("AddIntegers类析构函数执行!\n");
}
// If the constructor and destructor are not enough for setting up
// and cleaning up each test, you can define the following methods:
void SetUp() override {
// Code here will be called immediately after the constructor (right
// before each test).
printf("AddIntegers类TestCase级别SetUp函数执行!\n");
}
void TearDown() override {
// Code here will be called immediately after each test (right
// before the destructor).
printf("AddIntegers类TestCase级别TearDown函数执行!\n");
}
// Class members declared here can be used by all tests in the test suite
// for Foo.
};
// Tests that the Foo::Bar() method does Abc.
TEST_F(AddIntegers, TestAdd1) {
EXPECT_EQ(add(2, 3), 5);
}
// Tests that Foo does Xyz.
TEST_F(AddIntegers, TestAdd2) {
EXPECT_EQ(add(2, 1), 7);
}
} // namespace
} // namespace project
} // namespace my
testSubIntegers.cpp:
#include "stdio.h"
#include "gtest/gtest.h"
namespace mySub {
namespace projectSub {
namespace {
int sub(int a, int b)
{
return a - b;
}
// The fixture for testing class Foo.
class SubIntegers : public ::testing::Test {
protected:
// You can remove any or all of the following functions if their bodies would
// be empty.
static void SetUpTestSuite() {
// Avoid reallocating static objects if called in subclasses of FooTest.
printf("SubIntegers类TestSuite级别SetUp函数执行!\n");
}
// Per-test-suite tear-down.
// Called after the last test in this test suite.
// Can be omitted if not needed.
static void TearDownTestSuite() {
printf("SubIntegers类TestSuite级别TearDown函数执行!\n");
}
SubIntegers() {
// You can do set-up work for each test here.
printf("SubIntegers类构造函数执行!\n");
}
~SubIntegers() override {
// You can do clean-up work that doesn't throw exceptions here.
printf("SubIntegers类析构函数执行!\n");
}
// If the constructor and destructor are not enough for setting up
// and cleaning up each test, you can define the following methods:
void SetUp() override {
// Code here will be called immediately after the constructor (right
// before each test).
printf("SubIntegers类TestCase级别SetUp函数执行!\n");
}
void TearDown() override {
// Code here will be called immediately after each test (right
// before the destructor).
printf("SubIntegers类TestCase级别TearDown函数执行!\n");
}
// Class members declared here can be used by all tests in the test suite
// for Foo.
};
// Tests that the Foo::Bar() method does Abc.
TEST_F(SubIntegers, TestSub1) {
EXPECT_EQ(sub(9, 3), 6);
}
// Tests that Foo does Xyz.
TEST_F(SubIntegers, TestSub2) {
EXPECT_EQ(sub(2, 2), 0);
}
} // namespace
} // namespace project
} // namespace my
运行结果:
内容如有错误,敬请指正!