gtest的事件机制一共有三种:
在讲解事件机制之前,先说明:1、gtest可以脱离main函数执行。
2、如果必须使用main函数,main函数要放到命名空间外面
3、启动测试时所有使用TEST宏、TEST_F宏、TEST_P宏的测试案例都会被执行。
实现全局的事件机制,需要创建一个自己的类,然后继承testing::Environment类,然后分别实现成员函数SetUp()和TearDown(),同时在main函数内进行调用,即添加以下代码:“testing::AddGlobalTestEnvironment(new MyEnvironment);”,通过调用函数我们可以添加多个全局的事件机制。
实例代码如下(以下所有示例代码运行在VS2022中):
#include "gtest/gtest.h"
int add(int a,int b)
{
return (a + b);
}
class Client:public testing::Environment {
public:
void SetUp()
{
std::cout << "全局的事件机制(针对整个测试程序) SetUp " << std::endl;
};
void TearDown()
{
std::cout << "全局的事件机制(针对整个测试程序) TearDown " << std::endl;
};
};
TEST(IsAddTest, HandlerTrueReturn1) {
EXPECT_EQ(3, add(2, 1));
}
TEST(IsAbsTest, HandlerTrueReturn2)
{
EXPECT_TRUE(Abs(1) == 1) << "Abs(1) 期望等于 1"; //ASSERT_TRUE期待结果是true,operator<<输出一些自定义的信息
EXPECT_TRUE(Abs(-1) == 1) << "Abs(-1)=1";
int main(int argc, char* argv[]) {
testing::AddGlobalTestEnvironment(new Client);
testing::InitGoogleTest(&argc, argv);//将命令行参数传递给gtest
return RUN_ALL_TESTS(); //RUN_ALL_TESTS()运行所有测试案例
};
运行结果如下: SetUp()函数是在所有测试开始前执行,TearDown()函数是在所有测试结束后执行
如果修改test case名称为类名称:Client,运行不会报错,代码改动部分如下:
TEST(**Client**, HandlerTrueReturn1) {
EXPECT_EQ(3, add(2, 1));
}
TEST(**Client**, HandlerTrueReturn2)
{
EXPECT_TRUE(Abs(1) == 1) << "Abs(1) 期望等于 1"; //ASSERT_TRUE期待结果是true,operator<<输出一些自定义的信息
EXPECT_TRUE(Abs(-1) == 1) << "Abs(-1)=1";
运行结果如下:
测试套件的事件机制我们同样需要去创建一个类,继承testing::Test,实现两个静态(static)函数SetUpTestCase()和TearDownTestCase(),测试套件的事件机制不需要像全局事件机制一样在main注册,而是需要将我们平时使用的TEST宏改为TEST_F宏。
SetUpTestCase()函数是在测试套件第一个测试用例开始前执行。
TearDownTestCase()函数是在测试套件最后一个测试用例结束后执行。
注:TEST_F的第一个参数使我们创建的类名,也就是当前测试套件的名称。
多个测试场景需要相同数据配置的情况,用TEST_F
示例代码如下:
#include "gtest/gtest.h" #includeusing namespace std; class jj :public testing::Test { public: static void SetUpTestCase() { std::cout << "局部事件机制,针对TestSuite事件 good good study" << std::endl; } static void TearDownTestCase() { std::cout << "局部事件机制,针对TestSuite事件 day day up" << std::endl; } }; int add_number(int a, int b) { return (a + b); } int reduce_number(int a, int b) { return (a - b); } TEST_F(jj,add_num) { //此时使用的是TEST_F宏,test case名称都为类名:jj EXPECT_EQ(3, add_number(1, 2)); std::cout << "add_num ASSERT SUCCEED!" << std::endl; } TEST_F(jj, reduce_num) { EXPECT_EQ(2, reduce_number(3, 1)); std::cout << "reduce_num ASSERT SUCCEED!" << std::endl; }
运行结果如下:
class gyy:public testing::Test {
public:
static void SetUpTestCase() {
std::cout << "局部事件机制 TearDownTestCase " << std::endl;
}
static void TearDownTestCase() {
std::cout << "局部事件机制 TearDownTestCase " << std::endl;
}
};
TEST(gyy, TestName0) {
EXPECT_EQ(1, add(0,1));
EXPECT_TRUE(add(1, 0))<<"故意出的错误";
EXPECT_EQ(10, add(5, 5));
EXPECT_EQ(100, add(50, 50));
}
TEST_F(gyy, TestName1) {
EXPECT_EQ(2,add(1, 1));
}
运行结果:
测试用例的事件机制的创建和测试套件的基本一样,不同地方在于测试用例实现的两个函数分别是SetUp()和TearDown(),这两个函数不是静态函数。
SetUp()函数是在一个测试用例的开始前执行。TearDown()函数是在一个测试用例的结束后执行。
示例代码如下:
#include "gtest/gtest.h" #includeusing namespace std; class TestMap :public testing::Test { public: //加了Virtual关键字的函数就是虚拟函数,在基类的派生类中就可以通过重写虚拟函数来实现对基类虚拟函数的覆盖。 virtual void SetUp() //TEST跑之前会执行SetUp { cout << "我是每个方法之前都会执行的SetUp" << endl; test_map.insert(make_pair(1, 0)); test_map.insert(make_pair(2, 1)); test_map.insert(make_pair(3, 2)); test_map.insert(make_pair(4, 3)); test_map.insert(make_pair(5, 4)); } virtual void TearDown() //TEST跑完之后会执行TearDown { cout << "我是每个方法之后都会执行的TearDown" << endl; test_map.clear(); } map test_map; }; TEST_F(TestMap, Find) //此时使用的是TEST_F宏 { map ::iterator it = test_map.find(1); ASSERT_NE(it, test_map.end()); cout << "find函数断言成功" << endl; } TEST_F(TestMap, Size) { ASSERT_EQ(test_map.size(), 5)<<"字典大小等于5"; cout << "Size函数断言成功" << endl; }
执行结果如下:
TEST_F与TEST的区别是,TEST_F提供了一个初始化函数(SetUp)和一个清理函数(TearDown),在TEST_F中使用的变量可以在初始化函数SetUp中初始化,在TearDown中销毁,并且所有的TEST_F是互相独立的,都是在初始化以后的状态开始运行,一个TEST_F不会影响另一个TEST_F所使用的数据
总结如下:
**
- 在同一份TestCase中不能同时出现TEST和TEST_F两者进行混用;
- 局部事件机制、个体事件机制 继承类testing::Test,使用TEST_F宏
- 全局事件机制继承继承类testing::Environment**,同时在main函数内进行调用,即添加以下代码:testing::AddGlobalTestEnvironment(new MyEnvironment); 和使用哪种宏无关
**



