GTest的安裝與使用


安裝GTest

1、安裝源代碼

下載gtest,release-1.8.0

       git clone https://github.com/google/googletest

gtest編譯

  cd googletest

生成Makefile文件(先安裝cmake,brew install cmake),繼續輸入命令編譯:

  cmake CMakeLists.txt

執行make,生成兩個靜態庫:libgtest.a libgtest_main.a

  make

拷貝到系統目錄,注意,如果下訴目錄位置在不同版本位置有變動,用find . -name "libgtest*.a" 找到位置

       sudo cp libgtest*.a  /usr/lib

  sudo cp –a include/gtest /usr/include

檢查是否安裝成功

  可以寫一個簡單的測試代碼如下:

#include<gtest/gtest.h>
int add(int a,int b){
    return a+b;
}
TEST(testCase,test0){
    EXPECT_EQ(add(2,3),5);
}
int main(int argc,char **argv){
  testing::InitGoogleTest(&argc,argv);
  return RUN_ALL_TESTS();
}

在該文件的終端輸入編譯指令:

         gqx@gqx-Lenovo-Product:~/workplace/aaaa$ g++  test.cc -lgtest -lpthread

         gqx@gqx-Lenovo-Product:~/workplace/aaaa$ ./a.out

即得到如下顯示結果:

GTest的一些基本概念

  要測試一個類或函數,我們需要對其行為做出斷言。當一個斷言失敗時,Google Test會在屏幕上輸出該代碼所在的源文件及其所在的位置行號,以及錯誤信息。也可以在編寫斷言時,提供一個自定義的錯誤信息,這個信息在失敗時會被附加在Google Test的錯誤信息之后。

     斷言常常成對出現,它們都測試同一個類或者函數,但對當前功能有着不同的效果。ASSERT_*版本的斷言失敗時會產生致命失敗,並結束當前函數。EXPECT_*版本的斷言產生非致命失敗,而不會中止當前函數。通常更推薦使用EXPECT_*斷言,因為它們運行一個測試中可以有不止一個的錯誤被報告出來。但如果在編寫斷言如果失敗,就沒有必要繼續往下執行的測試時,你應該使用ASSERT_*斷言。 因為失敗的ASSERT_*斷言會立刻從當前的函數返回,可能會跳過其后的一些的清潔代碼,這樣也許會導致空間泄漏。

GTest的斷言

1、布爾值檢查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_TRUE(condition);

EXPECT_TRUE(condition);

condition is true

ASSERT_FALSE(condition);

EXPECT_FALSE(condition);

condition is false

 2、數值型數據檢查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_EQ(expected, actual);

EXPECT_EQ(expected, actual);

expected == actual

ASSERT_NE(val1, val2);

EXPECT_NE(val1, val2);

val1 != val2

ASSERT_LT(val1, val2);

EXPECT_LT(val1, val2);

val1 < val2

ASSERT_LE(val1, val2);

EXPECT_LE(val1, val2);

val1 <= val2

ASSERT_GT(val1, val2);

EXPECT_GT(val1, val2);

val1 > val2

ASSERT_GE(val1, val2);

EXPECT_GE(val1, val2);

val1 >= val2

 3、字符串比較

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_STREQ(expected_str, actual_str);

EXPECT_STREQ(expected_str, actual_str);

兩個C字符串有相同的內容

ASSERT_STRNE(str1, str2);

EXPECT_STRNE(str1, str2);

兩個C字符串有不同的內容

ASSERT_STRCASEEQ(expected_str, actual_str);

EXPECT_STRCASEEQ(expected_str, actual_str);

兩個C字符串有相同的內容,忽略大小寫

ASSERT_STRCASENE(str1, str2);

EXPECT_STRCASENE(str1, str2);

兩個C字符串有不同的內容,忽略大小寫

 4、異常檢查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_THROW(statement, exception_type);

EXPECT_THROW(statement, exception_type);

statement throws an exception of the given type

ASSERT_ANY_THROW(statement);

EXPECT_ANY_THROW(statement);

statement throws an exception of any type

ASSERT_NO_THROW(statement);

EXPECT_NO_THROW(statement);

statement doesn't throw any exception

5、浮點型檢查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_FLOAT_EQ(expected, actual);

EXPECT_FLOAT_EQ(expected, actual);

the two float values are almost equal

ASSERT_DOUBLE_EQ(expected, actual);

EXPECT_DOUBLE_EQ(expected, actual);

the two double values are almost equal

 對相近的兩個數比較:

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_NEAR(val1, val2, abs_error);

EXPECT_NEAR(val1, val2, abs_error);

the difference between val1 and val2 doesn't exceed the given absolute error

6、此外還有類型檢查、謂詞檢查等

事件機制

全局事件

要實現全局事件,必須寫一個類,繼承testing::Environment類,實現里面的SetUp和TearDown方法。

1. SetUp()方法在所有案例執行前執行

2. TearDown()方法在所有案例執行后執行

還需要告訴gtest添加這個全局事件,我們需要在main函數中通過testing::AddGlobalTestEnvironment方法將事件掛進來,也就是說,我們可以寫很多個這樣的類,然后將他們的事件都掛上去。

TestSuite事件

我們需要寫一個類,繼承testing::Test,然后實現兩個靜態方法

1. SetUpTestCase() 方法在第一個TestCase之前執行

2. TearDownTestCase() 方法在最后一個TestCase之后執行

在編寫測試案例時,我們需要使用TEST_F這個宏,第一個參數必須是我們上面類的名字,代表一個TestSuite。

TestCase事件

TestCase事件是掛在每個案例執行前后的,實現方式和上面的幾乎一樣,不過需要實現的是SetUp方法和TearDown方法:

1. SetUp()方法在每個TestCase之前執行

2. TearDown()方法在每個TestCase之后執行

以下案例解決說明上述三個事件的使用

#include<gtest/gtest.h>
#include<map>
#include<iostream>
using namespace std;
class Student{
public:
	Student(){
	    age=0;
	}
	Student(int a){
	    age=a;
	}
	void print(){
	cout<<"*********** "<<age<<" **********"<<endl;;
    	}	
private:
	int age;
};
class FooEnvironment : public testing::Environment{
public:
    virtual void SetUp()
    {
        std::cout << "Foo FooEnvironment SetUP" << std::endl;
    }
    virtual void TearDown()
    {
        std::cout << "Foo FooEnvironment TearDown" << std::endl;
    }
};
static Student *s;
//在第一個test之前,最后一個test之后調用SetUpTestCase()和TearDownTestCase()
class TestMap:public testing::Test
{
public:
    static void SetUpTestCase()
    {
        cout<<"SetUpTestCase()"<<endl;
	s=new Student(23);
    }

    static void TearDownTestCase()
    {
	delete s;
        cout<<"TearDownTestCase()"<<endl;
    }
    void SetUp()
    {
        cout<<"SetUp() is running"<<endl;
        
    }
    void TearDown()
    {
        cout<<"TearDown()"<<endl;
    }  
};

TEST_F(TestMap, Test1)
 {

    // you can refer to s here
    s->print();
}
int main(int argc, char** argv)
{
    testing::AddGlobalTestEnvironment(new FooEnvironment);
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

  相關結果和說明如下:

 參數化

       當考慮多次要為被測函數傳入不同的值的情況時,可以按下面的方式去測試。必須添加一個類,繼承testing::TestWithParam<T>。其中T就是你需要參數化的參數類型,如下面的案例是int型參數。(官方文檔上的案例)

#include<gtest/gtest.h>
// Returns true iff n is a prime number.
bool IsPrime(int n)
{
    // Trivial case 1: small numbers
    if (n <= 1) return false;
    // Trivial case 2: even numbers
    if (n % 2 == 0) return n == 2;
    // Now, we have that n is odd and n >= 3.
    // Try to divide n by every odd number i, starting from 3
    for (int i = 3; ; i += 2) {
        // We only have to try i up to the squre root of n
        if (i > n/i) break;
        // Now, we have i <= n/i < n.
        // If n is divisible by i, n is not prime.
        if (n % i == 0) return false;
    }
    // n has no integer factor in the range (1, n), and thus is prime.
    return true;
}
class IsPrimeParamTest : public::testing::TestWithParam<int>{};
TEST_P(IsPrimeParamTest, HandleTrueReturn)
{
 int n =  GetParam();
 EXPECT_TRUE(IsPrime(n));
}
//被測函數須傳入多個相關的值
INSTANTIATE_TEST_CASE_P(TrueReturn, IsPrimeParamTest, testing::Values(3, 5, 11, 23, 17));
int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

  注:部分內容摘自網絡(http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM