本文摘自 gtest簡介及簡單使用 ,在此感謝作者的分享.
_____________________________________________________________________________________________________________________
在Ubuntu下編譯gtest步驟:在gtest-1.7.0.zip目錄下,依次執行:unzip gtest-1.7.0.zip ;
cd gtest-1.7.0 ; ./configure ; make ; cd lib ; mv .libs libs ;此時,會在gtest-1.7.0/lib/libs目錄下生成libgtest.a和libgtest_main.a庫(說明:gtest-1.7.0/lib下會生成libgtest.la和libgtest_main.la庫,.la為libtool生成的共享庫,其實是個配置文檔。lib下的libs文件剛開始生成時是隱藏文件,需要用mv指令轉成正常文件,libs除了libgtest.a和libgtest_main.a庫還有其它一些文件,沒有什么用,全部刪除即可)。
Ubuntu下舉例:(1)、在gtest-1.7.0同一目錄下新建一個test文件;(2)、此test文件夾下存放fun.h和gtest_test.cpp文件,fun.h文件內容與Windows下的fun.h內容完全一致;
(3)、gtest_test.cpp文件內容為:
1 #include "../gtest-1.7.0/include/gtest/gtest.h" 2 3 #include "fun.h" 4 5 6 7 TEST(fun, add) 8 9 { 10 11 EXPECT_EQ(1, add(2,-1)); 12 13 EXPECT_EQ(5, add(2,3)); 14 15 } 16 17 18 19 int main(int argc, char** argv) 20 21 { 22 23 ::testing::InitGoogleTest(&argc, argv); 24 25 return RUN_ALL_TESTS(); 26 27 }
(4)、將終端定位到/test目錄下,輸入 g++ -g gtest_test.cpp -o gtest_test -I../gtest-1.7.0/include -L../gtest-1.7.0/lib/libs -lgtest -lgtest_main -lpthread ;會在/test目錄下生成gtest_test執行文件;
(5)、執行 ./gtest_test 輸出信息與Windows下一致。
更通用的做法是:不必在每個平台下分別編譯生成靜態庫,可以直接使用/fused-src/gtest下的gtest.h和gtest-all.cc兩個文件,此兩個文件包含了所有你需要用到的Google Test的東西。如果沒有/fuse-src這個文件,可以使用/scripts/fuse_gtest_files.py這個文件生成,操作步驟是:(1)、配置好python;(2)、打開命令提示符,將其定位到/scripts文件夾下,輸入命令:python fuse_gtest_files.py fused_gtest ;會在/scripts文件夾下生成一個fused_gtest/gtest文件,里面包含gtest.h和gtest-all.cc兩個文件,此兩個文件和/fuse-src中的同名文件內容是完全一致的。
下面是對gtest的一些總結:
1. TEST(test_case_name, test_name)
TEST_F(test_fixture,test_name)
TEST宏的作用是創建一個簡單測試,它定義了一個測試函數,在這個函數里可以使用任何C++代碼並使用提供的斷言來進行檢查。
多個測試場景需要相同數據配置的情況,用TEST_F。
2. gtest中,斷言的宏可以分為兩類,一類是ASSERT系列,一類是EXPECT系列。
{ASSERT|EXPECT}_EQ(expected,actual): Tests that expected == actual
{ASSERT|EXPECT}_NE(v1,v2): Tests that v1 != v2
{ASSERT|EXPECT}_LT(v1,v2): Tests that v1 < v2
{ASSERT|EXPECT}_LE(v1,v2): Tests that v1 <= v2
{ASSERT|EXPECT}_GT(v1,v2): Tests that v1 > v2
{ASSERT|EXPECT}_GE(v1,v2): Tests that v1 >= v2
EXPECT_*和ASSERT_*的區別:(1)、EXPECT_*失敗時,案例繼續往下執行;(2)、ASSERT_*失敗時,直接在當前函數中返回,當前函數中ASSERT_*后面的語句將不會執行,退出當前函數,並非退出當前案例。
斷言:布爾值檢查、數值型數據檢查、字符串檢查、顯示成功或失敗、異常檢查、Predicate Assertions、浮點型檢查、Windows HRESULT assertions、類型檢查。
3. ::testing::InitGoogleTest(&argc,argv):gtest的測試案例允許接收一系列的命令行參數,將命令行參數傳遞給gtest,進行一些初始化操作。gtest的命令行參數非常豐富。
4. RUN_ALL_TESTS():運行所有測試案例。
5. 可以通過操作符"<<"將一些自定義的信息輸出,如在EXPECT_EQ(v1, v2)<< "thisis a error! "
6. gtest的事件一共有3種:(1)、全局的,所有案例執行前后;(2)、TestSuite級別的,在某一批案例中第一個案例前,最后一個案例執行后;(3)、TestCase級別的,每個TestCase前后。
全局事件:要實現全局事件,必須寫一個類,繼承testing::Environment類,實現里面的SetUp和TearDown方法。SetUp方法在所有案例執行前執行;TearDown方法在所有案例執行后執行。
TestSuite事件:需要寫一個類,繼承testing::Test,然后實現兩個靜態方法:(1)、SetUpTestCase方法在第一個TestCase之前執行;(2)、TearDownTestCase方法在最后一個TestCase之后執行。
TestCase事件:是掛在每個案例執行前后的,需要實現的是SetUp方法和TearDown方法。(1)、SetUp方法在每個TestCase之前執行;(2)、TearDown方法在每個TestCase之后執行。
每個基於gtest的測試過程,是可以分為多個TestSuite級別,而每個TestSuite級別又可以分為多個TestCase級別。這樣分層的結構的好處,是可以針對不同的TestSuite級別或者TestCase級別設置不同的參數、事件機制等,並且可以與實際測試的各個模塊層級相互對應,便於管理。
7. 參數化:必須添加一個類,繼承testing::TestWithParam<T>,其中T就是你需要參數化的參數類型。
8. 編寫死亡測試案例時,TEST的第一個參數,即test_case_name,請使用DeathTest后綴,原因是gtest會優先運行死亡測試案例,應該是為線程安全考慮。
9. testing::AddGlobalTestEnvironment(newFooEnvironment):在main函數中創建和注冊全局環境對象。
10. 對於運行參數,gtest提供了三種設置的途徑:(1)、系統環境變量;(2)、命令行參數;(3)、代碼中指定FLAG。
命令行參數:(1)、--gtest_list_tests:使用這個參數時,將不會執行里面的測試案例,而是輸出一個案例的列表;(2)、--gtest_filter:對執行的測試案例進行過濾,支持通配符;(3)、--gtest_also_run_disabled_tests:執行案例時,同時也執行被置為無效的測試案例;(4)、--gtest_repeat=[COUNT]:設置案例重復運行次數;(5)、--gtest_color=(yes|no|auto):輸出命令行時是否使用一些五顏六色的顏色,默認是auto;(6)、--gtest_print_time:輸出命令時是否打印每個測試案例的執行時間,默認是不打印的;(7)、--gtest_output=xml[:DIRECTORY_PATH\|:FILE_PATH:將測試結果輸出到一個xml中,如—gtest_output=xml:d:\foo.xml 指定輸出到d:\foo.xml ,如果不是指定了特定的文件路徑,gtest每次輸出的報告不會覆蓋,而會以數字后綴的方式創建;(8)、--gtest_break_on_failure:調試模式下,當案例失敗時停止,方便調試;(9)、--gtest_throw_on_failure:當案例失敗時以C++異常的方式拋出;(10)、--gtest_catch_exceptions:是否捕捉異常,gtest默認是不捕捉異常的,這個參數只在Windows下有效。
使用舉例:
foo.h
#ifndef __FOO_H__ #define __FOO_H__ int max(int a, int b) { return a>b?a:b; } #endif
foo_test.cpp
#include <bits/stdc++.h> #include <gtest/gtest.h> #include "foo.h" TEST(foo, max) { EXPECT_EQ(2, max(2,-1)); EXPECT_EQ(3, max(2,3)); } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
makefile
CPP=g++ CPPFLAGS=-g -Wall -std=c++11 LIBS=-L/usr/local/lib/gtest1.7.0 -lgtest_main -lgtest -pthread INCLUDE=-I. -I/usr/local/include/gtest1.7.0 OBJS= foo_test.o main:$(OBJS) # indent main.cpp -linux ${CPP} ${CPPFLAGS} ${INCLUDE} $(OBJS) -o xmain $(LIBS) clean: rm -f xmain *core* *~ ${OBJS}
編譯與運行,控制台輸入:
$make
$ ./xmain [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from foo [ RUN ] foo.max [ OK ] foo.max (0 ms) [----------] 1 test from foo (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. (0 ms total) [ PASSED ] 1 test.
使用時可能會出現的問題:
1.undefined reference to `pthread_key_create' (linker error)
1) You need to specify -pthread
after -lgtest
. The linker takes libraries in order, and only takes as much as it needs to resolve references which are undefined at that point.
2) Nope, the problem is with Gtest's build.
If you build it using the standard configure approach, it isn't supplying the -lpthread
correctly to create libgtest.so
. Hence, when you try building a final shared library that actually uses the pthread capability it fails.
Instead, use the Cmake approach:
cd gtest-1.7.0 mkdir build cd build cmake -DBUILD_SHARED_LIBS=ON .. make
And then manually install these into /usr/lib/
This version correctly links in libpthread into libgtest.
簡要說明
1
2
3
4
|
TEST(name1, name2)
{
EXPECT_EQ(value1, value2);
}
|
這是要執行的測試用例,后面是執行內容
name1:測試用例名稱
name2:測試名稱
這兩個參數都只起到提示作用,我們也可以這么使用
name1:類名
name2:方法名
或者
name1:文件名
name2:函數名
EXPECT_EQ(value1, value2);
用例執行成功時,期望value1和value2是相等的,相等才算通過測試,如上例中的:
EXPECT_EQ(2, max(2,-1));
max(2, -1)的執行結果值期望是2如果不等,則用例運行失敗。
1
2
3
4
5
|
int
main(
int
argc,
char
** argv)
{
::testing::InitGoogleTest(&argc, argv);
return
RUN_ALL_TESTS();
}
|
這個是main函數,InitGoogleTest會初始化一些環境變量,RUN_ALL_TESTS()會調用所有的TEST(name1, name2)