gtest學習教學(從0到1)

2022-12-15 21:00:29

gtest使用教學

1 簡介

之前對gtest一無所知,最近,找了些相關的資料,學習了下.這裡主要記錄了學習過程和相關知識點.

什麼是gtest: gtest測試框架是在不同平臺上(Linux,Mac OS X,Windows,Cygwin,Windows CE和Symbian)為編寫C++測試而生成的。它是基於xUnit架構的測試框架,支援自動發現測試,豐富的斷言集,使用者定義的斷言.

2 準備工作

無需linux虛擬機器器,Windows就可以,無需安裝任何專業軟體,但是要求可以上網.
是的,我們將直接在網頁上進行線上編碼,編譯,執行.還不知道如何線上編譯偵錯程式碼的,見上一篇文章

3 獲取gtest原始碼

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

我是用git小烏龜下載的.

也可以用其他方式,目的就是獲取原始碼:

4 建立工程

進入https://replit.com/
建立一個c++空白工程.

我的工程名叫test.
然後匯入原始碼.

選擇原生的gtest原始碼目錄.
成功後:

5 編譯gtest

  • 1 進入googletest,建立build資料夾(實際拼寫出了點問題)

    在shell下:
cd  googletest/bulid/
cmake ..
make


成功後得到靜態庫檔案:

將libgtest.a  libgtest_main.a拷貝到main.cpp同級目錄下(main.cpp自己建立)
cp googletest/bulid/lib/libgtest*.a .

6 測試

先搞個例子跑起來.
main.cpp

/* main.cpp
 * Created by 一條曉魚 on 2022/12/15.
 */
#include "gtest/gtest.h"
#include <iostream>
#include <string>

int add(int a, int b)
{
	return a + b;
}

TEST(fun, add_a)
{
	EXPECT_EQ(-3, add(-2,-1));
	EXPECT_EQ(-2, add(1,-3));
}

int main(int argc, char **argv){

    ::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();

	return 0;
}
g++ main.cpp  libgtest.a -lpthread -std=c++14 -I /home/runner/test/googletest/googletest/include -o m
./m
(由於gtest版本問題,12.x  必須c++14以上才能編譯通過,剛開始編譯用的11標準,一直報錯)
(有用的就是靜態庫和標頭檔案,將來移植的時候就是需要這兩個東西)


這樣就算可以用啦.後面具體講一下,gtest怎麼用.

7 gtest 怎麼用

  • 斷言
    分ASSERT_XXX 和 EXPECT_XXX兩類.
    區別:
    如果ASSERT_XXX 測試結果不通過,後面的測試就不會執行了.
    如果EXPECT_XXX 測試結果不通過,後面的測試會接著執行.
    布林斷言:單參斷言
    ASSERT_TRUE、ASSERT_FALSE、EXPECT_TRUE、EXPECT_FALSE
    數值斷言:雙參
    ASSERT_EQ、ASSERT_NE、ASSERT_LT、ASSERT_LE、ASSERT_GT、ASSERT_GE
    EXPECT_EQ、EXPECT_NE、EXPECT_LT、EXPECT_LE、EXPECT_GT、EXPECT_GE
    字串斷言
    ASSERT_STREQ、ASSERT_STRCASEEQ

  • TEST(test_suite_name,test_name)
    一個TEST()算是一個測試case.
    TEST(x,y)展開為x_y_TEST()這樣的函數
    比如測試add()函數,我們可以考慮多種測試情況:和為負數,和為正數,極限值測試.

/*
 * Created by 一條曉魚 on 2022/12/15.
 */
#include "gtest/gtest.h"
#include <iostream>
#include <string>

int add(int a, int b)
{
	return a + b;
}

TEST(add, negative)
{
	EXPECT_EQ(-3, add(-2,-1));
	EXPECT_EQ(-2, add(1,-3));
}

TEST(add, positive)
{
	EXPECT_EQ(1, add(2,-1));
	EXPECT_EQ(2, add(-1,3));
}

TEST(add, limit)
{
    int a = 0x7fffffff + 1;
    std::cout<<"a = "<<a<<"\n";
	EXPECT_EQ(a, add(0x7fffffff,1));
	EXPECT_EQ(0, add(0xffffffff,1));
}

int main(int argc, char **argv){

  ::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();

	return 0;
}

  • TEST_F(x,y)
    以下函數使用需要定義測試套類繼承::testing::Test,重新實現對應函數.
    SetUpTestSuite:static測試套級別,執行測試套第一個用例前執
    TearDownTestSuite: static 測試套級別,執行測試套最後一個用例後執行
    SetUp:virtual 測試套中每個測試用例開始時執行
    TearDown:virtrual 測試套中每個測試用例執行後執行
    x 為 class名.
/*
 * Created by 一條曉魚 on 2022/12/15.
 */
#include "gtest/gtest.h"
#include <iostream>
#include <string>

int add(int a, int b)
{
	return a + b;
}

TEST(add, negative)
{
	EXPECT_EQ(-3, add(-2,-1));
	EXPECT_EQ(-2, add(1,-3));
}

TEST(add, positive)
{
	EXPECT_EQ(1, add(2,-1));
	EXPECT_EQ(2, add(-1,3));
}

TEST(add, limit)
{
  int a = 0x7fffffff + 1;
  std::cout<<"a = "<<a<<"\n";
	EXPECT_EQ(a, add(0x7fffffff,1));
	EXPECT_EQ(0, add(0xffffffff,1));
}

class FooTest : public ::testing::Test {
 protected:
  // You can remove any or all of the following functions if their bodies would
  // be empty.

  FooTest() {
     // You can do set-up work for each test here.
  }

  ~FooTest() override {
     // You can do clean-up work that doesn't throw exceptions here.
  }
  static void SetUpTestSuite() {
    std::cout<<"===================run before first case..."<<std::endl;
  } 

  static void TearDownTestSuite() {
    std::cout<<"===================run after last case..."<<std::endl;
  }
  // If the constructor and destructor are not enough for setting up
  // and cleaning up each test, you can define the following methods:

  void SetUp() override {
    std::cout<<" =========================SetUp() \n";
     // Code here will be called immediately after the constructor (right
     // before each test).
  }

  void TearDown() override {
    std::cout<<" =========================TearDown() \n";
     // Code here will be called immediately after each test (right
     // before the destructor).
  }

  // Class members declared here can be used by all tests in the test suite
  // for Foo.
};

TEST_F(FooTest,test_a)
{
  EXPECT_EQ(2, add(0x7fffffff,1));
}

TEST_F(FooTest,test_b)
{
  EXPECT_EQ(1, add(0,1));
}

int main(int argc, char **argv){

  ::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();

	return 0;
}

上面兩個是常用的.基本上就是初級教學裡面的內容,高階教學後面有連結.

8 參考

初級教學
高階教學
csdn的教學