前言
在单元测试中,我们经常需要在某个测试套件、测试用例或者整个测试运行之前进行前置条件设置及检查,或者运行之后对运行结果进行校验等操作。在gtest中,称之为事件机制。gtest将事件按照作用的范围不同进行划分,从大到小总共分为3个层次:
1)整个测试层面,即在测试工程开始前和结束后进行;
2)测试套件层面,即在某个测试套件开始前和结束后进行;
3)测试用例层面,即在某个测试用例开始前和结束后进行;
2、测试层面事件实现
要实现测试层面的事件,我们需要继承testing::Environment类,首先我们来看一下这个类的定义:
- class Environment {
- public:
- virtual ~Environment() {}
-
-
- virtual void SetUp() {}
-
-
- virtual void TearDown() {}
- private:
- struct Setup_should_be_spelled_SetUp {};
- virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
- };
这个类中有两个虚函数:SetUp和TearDown。我们的子类只需要实现这个方法即可。其中在SetUp方法中实现所有测试启动之前需要完成的操作,而TearDown函数中实现所有测试运行结束后需要进行的操作。例如:
- class GlobalEvent2 :
- public testing::Environment
- {
- public:
-
- virtual void SetUp()
- {
- cout << "Before any case, Global 2" << endl;
- }
-
- virtual void TearDown()
- {
- cout << "After all cases done, Global 2" << endl;
- }
- };
然后,在main函数中,在RUN_ALL_TESTS()之前,我们调用如下语句:
testing::AddGlobalTestEnvironment(new GlobalEnvent);
将这个测试层面的的事件添加到事件列表即可。这样,在测试执行之前,系统会先执行GlobalEvent2的SetUp方法;在所有测试用例执行完之后,系统会执行GlobalEvent2的TearDown方法。另外,我们可以定义任意多个继承自testing::Environment的子类,以实现不同的全局事件。所有的子类的SetUp按照我们调用testing::AddGlobalTestEnvironment添加它们的先后顺序执行,而TearDown的执行顺序则与添加顺序相反。
3、测试套件层面事件
要在测试套件层面上定义事件,我们需要继承testing::Test类,并覆盖它的静态方法:SetUpTestCase和TearDownTestCase.在继续之前我们首先看看testing::Test类的定义:
从testing::Test类的声明可以看到,SetUpTestCase和TearDownTestCase为静态方法,并且它们的注释也很详细。在测试套件的第一个测试用例开始前,SetUpTestCase函数会被调用,而在测试套件中的最后一个测试用例运行结束后,TearDownTestCase函数会被调用。
4、测试用例层面的事件
要实现单个测试用例的事件,我们需要同样需要继承testing::Test类,并实现它的protected virtual方法SetUp和TearDown。gtest在运行这个测试用例之前,会首先调用SetUp方法,然后在测试用例结束之后,调用TearDown方法。
5、总结
通过gtest事件机制,我们可以让gtest在运行测试、测试套件、测试用例的前后分别运行指定的代码段。这一点很有用,比如在单元测试中,我们可以将初始化操作放入SetUp函数中,而资源回收等操作方在TearDown函数中实现,这样可以使得我们在测试用例中只需专注于测试即可。