0


【C++】Google Test(gtest)单元测试

文章目录

Google Test(gtest)单元测试

单元测试是一种软件测试方法,它旨在将应用程序的各个部分(通常是方法或函数)分离出来并独立测试,以确保每个部分都能够按预期工作。

gtest是Google公司发布的一款开源的C/C++单元测试框架。gtest的

TEST

宏用于定义单个测试用例,其基本语法为:

TEST(TestCaseName, TestName){// 测试代码}

其中

TestCaseName

为测试用例的名称,用于将相关的测试分组在一起,以便在测试结果中更容易地识别和归类。

TestName

为具体测试的名称,一般描述测试的目的。

每个测试用例包含一个或多个检查点,这些检查点使用断言来验证代码的行为。包括以

EXPECT_

为前缀的非致命断言,其在测试失败时程序会继续执行;和以

ASSERT_

味前缀的致命断言,其在测试失败时程序立即终止。基本的非致命断言包括:

  • EXPECT_EQ(val1, val2):检查 val1 == val2
  • EXPECT_NE(val1, val2):检查 val1 != val2
  • EXPECT_LT(val1, val2):检查 val1 < val2
  • EXPECT_LE(val1, val2):检查 val1 <= val2
  • EXPECT_GT(val1, val2):检查 val1 > val2
  • EXPECT_GE(val1, val2):检查 val1 >= val2

对应的致命断言:

  • ASSERT_EQ(val1, val2)
  • ASSERT_NE(val1, val2)
  • ASSERT_LT(val1, val2)
  • ASSERT_LE(val1, val2)
  • ASSERT_GT(val1, val2)
  • ASSERT_GE(val1, val2)

除此之外,还有专门用于字符串比较的断言:

  • EXPECT_STREQ(str1, str2):检查 str1str2 是相同的字符串。
  • EXPECT_STRNE(str1, str2):检查 str1str2 是不同的字符串。
  • EXPECT_STRCASEEQ(str1, str2):检查 str1str2 是相同的字符串,忽略大小写。
  • EXPECT_STRCASENE(str1, str2):检查 str1str2 是不同的字符串,忽略大小写。

用于浮点数比较的断言:

  • EXPECT_FLOAT_EQ(val1, val2):检查 val1val2 具有相同的浮点值。
  • EXPECT_DOUBLE_EQ(val1, val2):检查 val1val2 具有相同的双精度值。
  • EXPECT_NEAR(val1, val2, abs_error):检查 val1val2 之间的差值在 abs_error 范围内。

用于布尔值的断言:

  • EXPECT_TRUE(condition):检查 condition 为真。
  • EXPECT_FALSE(condition):检查 condition 为假。

使用示例

项目结构:

gtest_demo/
├── CMakeLists.txt
├── include/
│   └── math_functions.h
├── src/
│   └── math_functions.cpp
└── tests/
    └── test_math_functions.cpp

CMakeLists.txt

# 指定CMake的最低版本
cmake_minimum_required(VERSION 3.10)# 定义项目名称
project(gtest_demo)# 设置C++标准为C++11,并且为强制要求set(CMAKE_CXX_STANDARD 11)set(CMAKE_CXX_STANDARD_REQUIRED True)# 添加当前项目的include目录,以便编译器能找到头文件
include_directories(${PROJECT_SOURCE_DIR}/include)# 添加源文件,生成一个名为math_functions的静态库
add_library(math_functions src/math_functions.cpp)# 查找Google Test库,确保系统已安装GTest
find_package(GTest REQUIRED)# 添加GTest的include目录
include_directories(${GTEST_INCLUDE_DIRS})# 添加测试源文件,生成一个名为runTests的可执行文件
add_executable(runTests tests/test_math_functions.cpp)# 链接math_functions, gtest库和pthread库到可执行文件runTests# gtest框架在实现上使用了多线程(pthread)来管理测试并发执行
target_link_libraries(runTests ${GTEST_LIBRARIES} pthread math_functions)# 启用测试功能
enable_testing()# 添加一个名为runTests的测试
add_test(NAME runTests COMMAND runTests)

include/math_functions.h

#ifndefMATH_FUNCTIONS_H // 头文件保护#defineMATH_FUNCTIONS_Hintadd(int a,int b);intsubtract(int a,int b);floatadd(float a,float b);doubleadd(double a,double b);#endif

src/math_functions.cpp :

#include"math_functions.h"intadd(int a,int b){return a + b +1;// 故意错误}intsubtract(int a,int b){return a - b;}floatadd(float a,float b){return a + b;}doubleadd(double a,double b){return a + b;}

tests/test_math_functions.cpp:

#include<gtest/gtest.h>#include"math_functions.h"// 测试add函数(整数)TEST(MathFunctionsTest, AddInt){EXPECT_EQ(add(1,1),2);EXPECT_EQ(add(-1,-1),-2);EXPECT_EQ(add(0,0),2);}// 测试subtract函数TEST(MathFunctionsTest, Subtract){EXPECT_EQ(subtract(2,1),1);EXPECT_EQ(subtract(-1,-1),0);EXPECT_EQ(subtract(0,0),0);}// 测试add函数(浮点数)TEST(MathFunctionsTest, AddFloat){EXPECT_FLOAT_EQ(add(0.1f,0.2f),0.3f);EXPECT_NEAR(add(0.1f,0.2f),0.3f,1e-6);}TEST(MathFunctionsTest, AddDouble){EXPECT_DOUBLE_EQ(add(0.1,0.2),0.3);EXPECT_NEAR(add(0.1,0.2),0.3,1e-6);}intmain(int argc,char**argv){::testing::InitGoogleTest(&argc, argv);// 初始化 Google Test returnRUN_ALL_TESTS();// 运行所有测试用例}

编译和运行测试

mkdir build
    cd build
    cmake..make
    ./runTest
[==========] Running 4 tests from 1 test case.[----------] Global test environment set-up.[----------] 4 tests from MathFunctionsTest
[ RUN      ] MathFunctionsTest.AddInt
/home/hrn/CppProjects/gtest_demo/tests/test_math_functions.cpp:6: Failure
      Expected: add(1, 1)
      Which is: 3
To be equal to: 2
/home/hrn/CppProjects/gtest_demo/tests/test_math_functions.cpp:7: Failure
      Expected: add(-1,-1)
      Which is: -1
To be equal to: -2
/home/hrn/CppProjects/gtest_demo/tests/test_math_functions.cpp:8: Failure
      Expected: add(0, 0)
      Which is: 1
To be equal to: 0
[  FAILED  ] MathFunctionsTest.AddInt (0 ms)[ RUN      ] MathFunctionsTest.Subtract
[       OK ] MathFunctionsTest.Subtract (0 ms)[ RUN      ] MathFunctionsTest.AddFloat
[       OK ] MathFunctionsTest.AddFloat (0 ms)[ RUN      ] MathFunctionsTest.AddDouble
[       OK ] MathFunctionsTest.AddDouble (0 ms)[----------] 4 tests from MathFunctionsTest (0 ms total)[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran.(0 ms total)[  PASSED  ] 3 tests.[  FAILED  ] 1 test, listed below:
[  FAILED  ] MathFunctionsTest.AddInt

 1 FAILED TEST

3个测试通过,1个不通过,

add

函数有误.

更多用法

测试夹具

测试夹具(Test Fixture)用于提供一个环境,允许开发者在多个测试用例之间共享设置和清理的代码,确保每个测试用例都在相同或可控的初始状态下运行。

在gtest中,测试夹具通常是通过派生自

::testing::Test

类的子类来实现的,并通过

TEST_F()

宏定义测试用例。

示例:

#include<gtest/gtest.h>#include<vector>// 假设有一个简单的类 MyClassclassMyClass{public:MyClass(int data):basevalue(data){}voidadd(int data){ basevalue += data;}intgetdata()const{return basevalue;}private:int basevalue;};// 测试夹具类classMyTest:public::testing::Test{protected:
    MyClass *my;
    std::vector<int> sharedVector;// 在每个测试用例执行前设置环境voidSetUp()override{
        my =newMyClass(100);
        sharedVector ={1,2,3,4,5};}// 在每个测试用例执行后清理环境voidTearDown()override{delete my;}};// 使用 TEST_F() 宏编写测试用例TEST_F(MyTest, test1){
    my->add(10);EXPECT_EQ(my->getdata(),110);

    sharedVector.push_back(6);EXPECT_EQ(sharedVector.size(),6);EXPECT_EQ(sharedVector.back(),6);}TEST_F(MyTest, test2){
    my->add(100);EXPECT_EQ(my->getdata(),200);

    sharedVector.pop_back();EXPECT_EQ(sharedVector.size(),4);EXPECT_EQ(sharedVector.back(),4);}TEST_F(MyTest, test3){
    my->add(-50);EXPECT_EQ(my->getdata(),50);

    sharedVector[0]=10;EXPECT_EQ(sharedVector[0],10);EXPECT_EQ(sharedVector.size(),5);}TEST_F(MyTest, test4){
    my->add(0);EXPECT_EQ(my->getdata(),100);

    sharedVector.clear();EXPECT_TRUE(sharedVector.empty());}

在这个示例中,测试夹具类

MyTest

通过继承

::testing::Test

类,实现了

SetUp()

TearDown()

方法。在

SetUp()

方法中,初始化了一个

MyClass

对象和一个

std::vector<int>

。在

TearDown()

方法中,清理了

MyClass

对象。

每个测试用例 (

test1

test2

test3

test4

) 都使用了相同的测试夹具

MyTest

,共享了初始化和清理代码。在每个测试用例中,

MyClass

对象和

sharedVector

都被重新初始化,以确保测试用例之间相互独立。

标签: c++ 单元测试

本文转载自: https://blog.csdn.net/weixin_44378835/article/details/140218680
版权归原作者 二进制人工智能 所有, 如有侵权,请联系我们删除。

“【C++】Google Test(gtest)单元测试”的评论:

还没有评论