測試套件:在多個測試中使用同樣的數據配置
當你發現自己編寫了兩個或多個測試來操作同樣的數據,你可以采用一個測試固件。它讓你可以在多個不同的測試中重用同樣的對象配置。
要創建測試固件,只需:
- 創建一個類繼承自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變量標識,對象析構后進行恢復。
文章來源于領測軟件測試網 http://www.kjueaiud.com/