Linux x86環境下
一,gtest安裝
下載gtest源碼包:gtest-1.7.0.zip
解壓后進入gtest-1.7.0目錄
cmake CMakeLists.txt
make 后生成兩個靜態庫:libgtest.a libgtest_main.a
sudo cp libgtest*.a /usr/lib
sudo cp –a include/gtest /usr/include
下面是進入到sample目錄下編譯用例
cd sample
g++ sample1.cc sample1_unittest.cc -lgtest -lgtest_main -lpthread -o test1
g++ sample1.cc sample3-inl.h sample5_unittest.cc -lgtest -lgtest_main -lpthread -o test5
由於sample1.cc和sample1_unittest.cc文件中沒有編寫main函數,這里需要鏈接libgtest_main.a庫
二,gtest使用
http://www.cnblogs.com/coderzh/archive/2009/04/06/1430364.html
gtest 即 Google C++單元測試框架
單元測試一般由編碼人員自己完成,它的目的是隔離程序部件,並證明這些單個部件滿足預期的功能。
它提供了豐富的斷言、致命和非致命失敗判斷,能進行值參數化測試、類型參數化測試、“死亡測試”
1,斷言
ASSERT_* 系列的斷言,當檢查點失敗時,退出當前函數(注意:並非退出當前案例)
EXPECT_* 系列的斷言,當檢查點失敗時,繼續往下執行。
<1>布爾類型檢查
ASSERT_TRUE(condition) ASSERT_FALSE(condition)
<2>數值類型檢查
ASSERT_EQ(expected, actual);
ASSERT_NE(val1, val2);
ASSERT_LT(val1, val2);
ASSERT_LE(val1, val2);
ASSERT_GT(val1, val2);
ASSERT_GE(val1, val2);
<3>字符串檢查
ASSERT_STREQ(expected_str, actual_str);
ASSERT_STRNE(str1, str2);
ASSERT_STRCASEEQ(expected_str, actual_str);
ASSERT_STRCASENE(str1, str2);
一個簡單的測試案例,可以參考sample/sample1.cc 和sample1_unittest.cc
另外sample2 是對類的接口函數的測試。
首先是一個求最大公約數的函數
int Foo(int a, int b) |
下面是對這個函數寫一個簡單的測試樣例
#include <gtest/gtest.h> |
每個案例(TEST或TEST_F)應該是相互獨立,互不影響的。
TEST宏有兩個參數,第一個是TestSuiteName,第二個是TestCaseName
然后在main中添加如下代碼讓我們的案例運行起來。
int _tmain(int argc, _TCHAR* argv[]) |
也可以不寫main函數,直接在編譯的時候鏈接libgtest_main.a庫
2,gtest提供了多種事件機制,非常方便我們在案例之前或之后做一些操作。總結一下gtest的事件一共有3種:
<1>全局的,所有案例執行前后。
<2>TestSuite級別的,在某一批案例中第一個案例前,最后一個案例執行后。
<3> TestCase級別的,每個TestCase前后。
這里主要介紹TestCase事件
TestCase事件是掛在每個案例執行前后的,不過需要實現的是SetUp方法和TearDown方法:
1. SetUp()方法在每個TestCase之前執行
2. TearDown()方法在每個TestCase之后執行
要寫一個類,這個類繼承 testing::Test類。
class FooCalcTest:public testing::Test |
寫測試案例時,使用TEST_F則開始測試前調用SetUp,結束案例后調用TearDown。也可以在這個類中定義其他的測試函數,供TEST_F調用。TEST_F的第一個參數類的名字,第二個參數是測試案例名。
gtest源碼中的sample3也用的是TestCase事件。這個例子中定義了一個Queue模板,在QueueTest類中定義了SetUp函數和一個用來測試Map的MapTester函數。
3,參數化測試(mytest2)
首先必須添加一個類,繼承testing::TestWithParam<T>,其中T就是你需要參數化的參數類型,這里是int。
然后使用TEST_P定義參數化案例。在TEST_P宏里,使用GetParam()獲取當前的參數的具體值。
最后 使用INSTANTIATE_TEST_CASE_P這宏來告訴gtest你要測試的參數范圍
#include <gtest/gtest.h> |
INSTANTIATE_TEST_CASE_P宏的三個參數:
第一個參數是測試案例的前綴,可以任意取。
第二個參數是測試案例的名稱,需要和之前定義的參數化的類的名稱相同,如:IsPrimeParamTest
第三個參數是可以理解為參數生成器,上面的例子使用test::Values表示使用括號內的參數。Google提供了一系列的參數生成的函數:
Range(begin, end[, step]) |
范圍在begin~end之間,步長為step,不包括end |
Values(v1, v2, ..., vN) |
v1,v2到vN的值 |
ValuesIn(container) and ValuesIn(begin, end) |
從一個C類型的數組或是STL容器,或是迭代器中取值 |
Bool() |
取false 和 true 兩個值 |
Combine(g1, g2, ..., gN) |
這個比較強悍,它將g1,g2,...gN進行排列組合,g1,g2,...gN本身是一個參數生成器,每次分別從g1,g2,..gN中各取出一個值,組合成一個元組(Tuple)作為一個參數。 說明:這個功能只在提供了<tr1/tuple>頭的系統中有效。gtest會自動去判斷是否支持tr/tuple,如果你的系統確實支持,而gtest判斷錯誤的話,你可以重新定義宏GTEST_HAS_TR1_TUPLE=1。 |
4,命令行參數
--gtest_output=xml:dir:\foo.xml
指定輸出到dir\foo.xml,不指定則輸出到當前目錄。也可以由系統變量GTEST_OUTPUT指定
--gtest_list_tests
使用這個參數時,將不會執行里面的測試案例,而是輸出一個案例的列表。
--gtest_filter
對執行的測試案例進行過濾,支持通配符
好的單元測試具備以下特點:
1, 獨立:即該測試用例的測試結果不受其他測試的影響
2, 有效的組織架構,清晰的命名:各個測試用例針對不同的測試對象,而對單個測試對象而言,又可能有多個測試用例對應該對象的多個功能。好的習慣是把這些用例以層次結構的形式組織起來,並使用清晰的命名,使得我們通過閱讀用例名稱即可明了該用例的功能
3, 可移植、可復用
4, 當用例失敗時,提供盡可能多的有效信息