测试套件:在多个测试中使用同样的数据配置
当你发现自己编写了两个或多个测试来操作同样的数据,你可以采用一个测试固件。它让你可以在多个不同的测试中重用同样的对象配置。
要创建测试固件,只需:
- 创建一个类继承自testing::Test。将其中的成员声明为protected:或是public:,因为我们想要从子类中存取固件成员。
- 在该类中声明你计划使用的任何对象。
- 如果需要,编写一个默认构造函数或者SetUp()函数来为每个测试准备对象。常见错误包括将SetUp()拼写为Setup()(小写了u)——不要让它发生在你身上。
- 如果需要,编写一个析构函数或者TearDown()函数来释放你在SetUp()函数中申请的资源。要知道什么时候应该使用构造函数/析构函数,什么时候又应该使用SetUp()/TearDown()函数,阅读我们的FAQ。
- 如果需要,定义你的测试所需要共享的子程序。
当我们要使用固件时,使用TEST_F()替换掉TEST(),它允许我们存取测试固件中的对象和子程序:
TEST_F(test_case_name, test_name) {
... test body ...
}
与TEST()一样,第一个参数是测试案例的名称,但对TEST_F()来说,这个名称必须与测试固件类的名称一 些。你可能已经猜到了:_F正是指固件。
不幸地是,C++宏系统并不允许我们创建一个单独的宏来处理两种类型的测试。使用错误的宏会导致编译期的错误。
而且,你必须在TEST_F()中使用它之前,定义好这个测试固件类。否则,你会得到编译器的报错:“virtual outside class declaration”。
对于TEST_F()中定义的每个测试,Google Test将会:
- 在运行时创建一个全新的测试固件
- 马上通过SetUp()初始化它,
- 运行测试
- 调用TearDown()来进行清理工作
- 删除测试固件。注意,同一测试案例中,不同的测试拥有不同的测试固件。Google Test在创建下一个测试固件前总是会对现有固件进行删除。Google Test不会对多个测试重用一个测试固件。测试对测试固件的改动并不会影响到其他测试。
例如,让我们为一个名为Queue的FIFO队列类编写测试,该类的接口如下:
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;
...
};
首先,定义一个固件类。习惯上,你应该把它的名字定义为FooTest,这里的Foo是被测试的类:
class QueueTest : public testing::Test {
protected:
virtual void SetUp() {
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// virtual void TearDown() {}
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};
在这个案例中,我们不需要TearDown(),因为每个测试后除了析构函数外不需要进行清理工作了。
接下来我们使用TEST_F()和这个固件来编写测试。
TEST_F(QueueTest, IsEmptyInitially) {
EXPECT_EQ(0, q0_.size());
}
TEST_F(QueueTest, DequeueWorks) {
int* n = q0_.Dequeue();
EXPECT_EQ(NULL, n);
n = q1_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(1, *n);
EXPECT_EQ(0, q1_.size());
delete n;
n = q2_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(2, *n);
EXPECT_EQ(1, q2_.size());
delete n;
}
上面这段代码既使用了ASSERT_*断言,又使用了EXPECT_*断言。经验上讲,如果你想要断言失败后,测试能够继续进行以显示更多的错误时,你应该使用EXPECT_*断言;使用ASSERT_*如果该断言失败后继续往下执行毫无意义。例如,Dequeue测试中的第二个断言是ASSERT_TURE(n!= NULL),因为我们随后会n指针解引用,如果n指针为NULL的话,会导致一个段错误。
当这些测试开始时,会发生如下情况:
- Google Test创建一个QueueTest对象(我们把它叫做t1)。
- t1.SetUp()初始化t1。
- 第一个测试(IsEmptyInitiallly)在t1上运行。
- 测试完成后,t1.TearDown()进行一些清理工作。
- t1被析构。
- 以上步骤在另一个QueueTest对象上重复进行,这回会运行DequeueWorks测试。
有效平台: Linux, Windows, Mac.
Note: 当一个测试对象被构造时,Google Test会自动地保存所有的Google Test变量标识,对象析构后进行恢复。
文章来源于领测软件测试网 https://www.ltesting.net/