【C++中级篇】gtest的使用方法及cmake配置

个人箴言:

不积跬步,无以至千里;不积小流,无以成江海。夯实基础,成就高楼大厦。

前言:

在一项c++工程中,会存在很多类,很多功能方法,如果每个对外的接口方法都通过在业务中发现问题,是一件相当糟糕的事儿,而且效率低下。如果针对每个接口都设计一个主函数进行验证,需要运行很多程序,为解决这个问题,单元测试模块应运而生,本期探讨下由google开发的单元测试模块gtest的使用方法。

gtest的下载

gtest目前已经开源,可以通过github进行下载

国内镜像加速链接

使用cmake进行安装,如何使用cmake进行第三方库文件安装,可自行百度,本篇着重介绍gtest的使用方法。

gtest的格式

gtest目前提供有TEST、TEST_F、TEST_P三个宏,常用的断言有强断言ASSERT_*,弱断言EXPECT_*.

强断言之后,不在继续进行验证,一般用于第一个测试用例如果失效后,后面测试就没有意义的断言。

弱断言之后,会报错,程序继续往下运行,一版用于测试相互独立的测试用例。

有关断言的类型有很多,相等,不相等,大于,大于等于,小于等于等等,具体可以参考https://cloud.tencent.com/developer/article/2157991

先写测试文本,再进行一一解释。

首先,我们先写我们的功能函数,此时还没有gtest的任何事情,专注于开发,比如我们设计一个计算器。

//calculation.h
#pragma once
#include <vector>
class Calculation{
  public:
  Calculation() = default ;
  ~Calculation() = default;
  template<typename T>
  T add(T t1,T t2){
    return t1 + t2;
  };
  double DotSelf(double p);
  double base_num;

};

功能实现为:

//calculation.cc
#include "calculation.h"

double Calculation::DotSelf(double p){
  return base_num * p;
}

至此我们已经写了一个简单的计算器,能够实现基础的加法运算和一个和自身相乘的运算;接着我们写测试用例,新建文件为calculation_test.cc,这个文件名一般命名规则为[类名]_test.cc,名字没有特殊规定,只是约定俗成,方便观察是针对哪个文件的测试用例文件。

新建calculation_test.cc

#pragma once
#include <vector>
#include <iostream>
#include "gtest/gtest.h"
#include "src/calculation.h"
using std::cout;
using std::endl;

//第一个参数:测试套件名,第二个参数:测试特例名
TEST(addDouble,Mytest){
  Calculation obj;
  EXPECT_EQ(4.3,obj.add(1.2,3.1));
}

TEST(addint,Mytest){
  Calculation obj;
  EXPECT_EQ(4,obj.add(1,3));
}

class CalculationTest : public testing::Test{
  protected:
  //下面的函数都非必须的,如果是空的可以进行删除

    CalculationTest() {
        // 可以在这个里面做一些初始化.
    cout<<"构造函数"<<endl;
    }

    virtual ~CalculationTest() {
        //做一些析构功能
    cout<<"析构函数"<<endl;
    
    }

    virtual void SetUp() {
        //构造函数之后,测试执行之前执行语句
    cout<<"SetUp"<<endl;
    }

    virtual void TearDown() {
    //测试结束后执行语句,在析构函数执行前执行
    cout<<"TearDown"<<endl;
    }

    // 包含测试主体
    Calculation p;

};


TEST_F(CalculationTest,test1){
  p.base_num = 2;
  cout<<"2"<<endl;
  EXPECT_EQ(4,p.DotSelf(2));
}

TEST_F(CalculationTest,test2){
  cout<<"6"<<endl;
  EXPECT_EQ(6,p.DotSelf(3));//因为已经给base_num赋值(在test1中),所以计算结果为6
}

编写可执行程序主函数

新建test_main.cc

#include "gtest/gtest.h"

int main(int argc,char** argv){
  testing::InitGoogleTest(&argc,argv);
  return  RUN_ALL_TESTS();
}

cmake文件编写,新建CMakeLists.txt,并写到

project(gtest_test)
cmake_minimum_required(VERSION 3.1.6)
#编译glog
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib)

#设置库文件的编译目录
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRCS)

#设置gtest的头文件基准目录
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
#设置头文件基本目录
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

#生成动态链接库
add_library(cal_lib SHARED ${SRCS})


#${CMAKE_CURRENT_SOURCE_DIR}/test/test_main.cc   ${CMAKE_CURRENT_SOURCE_DIR}/src/calculation_test.cc
#指定测试的cc文件,编译生成单元测试的可执行文件
add_executable(test_exe   ${CMAKE_CURRENT_SOURCE_DIR}/test/calculation_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_main.cc)
#动态链接库链接,如果add_executable中包含有 main()函数,就不必链接gtest_main,否则需要链接gtest_main指定main函数
target_link_libraries(test_exe gtest cal_lib)

编译会生成test_exe文件,运行后会执行所有的测试用例。本例子的输出为:

Running main() from gtest_main.cc
[==========] Running 4 tests from 3 test cases.
[----------] Global test environment set-up.
[----------] 1 test from addDouble
[ RUN      ] addDouble.Mytest
[       OK ] addDouble.Mytest (0 ms)
[----------] 1 test from addDouble (0 ms total)

[----------] 1 test from addint
[ RUN      ] addint.Mytest
[       OK ] addint.Mytest (0 ms)
[----------] 1 test from addint (0 ms total)

[----------] 2 tests from CalculationTest
[ RUN      ] CalculationTest.test1
构造函数
SetUp
2
TearDown
析构函数
[       OK ] CalculationTest.test1 (0 ms)
[ RUN      ] CalculationTest.test2
构造函数
SetUp
6
TearDown
析构函数
[       OK ] CalculationTest.test2 (0 ms)
[----------] 2 tests from CalculationTest (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 3 test cases ran. (0 ms total)
[  PASSED  ] 4 tests.

TEST宏的使用与解释

TEST函数内有两个参数,假如TEST(a,b),a指的是测试主体,b可以指测试具体的方法,这两个参数可以随便写,但是不能有两个完全一样的TEST(a,b)。在运行测试用例的时候,输出会指出是在运行哪个测试用例下运行的。比如测试用例中的TEST(addDouble,Mytest)和TEST(addint,Mytest),会在生成中注明a.b的形式

TEST_F宏的使用与解释

当遇到测试时候我们需要进行比较复杂的初始化且多个测试case都需要依赖同一个初始化时,重复在TEST宏中进行初始化操作会增大代码的冗余,此时可以通过TEST_F实现。

第一步:新建一个类继承于testing::Test,并在里面包含有一个测试主体Calculation

第二步:编写TEST_F宏,宏中两个参数,第一个参数一定是第一步中的新建类名,第二个参数可以根据自己的需求自行定义。

第三步:编写构造函数,里面默认有两个SetUp函数和TearDown函数,分别调用发生在构造函数之后,测试执行之前执行语句 和 测试结束后执行语句,在析构函数执行前执行。

可以注意到,因为在test1中我们已经将base_num进行赋值,所以在test2中进行DotSelf的时候,就认为已经赋过值了。

gtest的注意事项

问题1:是否一定需要自己手写main函数?

答:否,gtest已经内嵌有main函数,可以在动态链接库链接的时候进行对gtest_main函数的依赖,这样就可以不用写main函数了

问题2:失败的案例分析有何提示?

我们尝试写一个错误的案例,分析下gtest的输出,我们把6更改为7

输出为:

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用CMakegtest进行项目编译和测试时,你可以按照以下步骤进行操作: 1. 首先,在项目的根目录下创建一个名为`CMakeLists.txt`的文件,并在其中添加相关配置。例如,你可以使用以下命令创建一个build文件夹并进行编译: ``` mkdir build && cd build cmake .. make ``` 这将编译你的项目并生成一个名为`MyProject`的可执行文件。 2. 如果你的项目中涉及到gtest,你还需要在项目根目录下创建一个名为`gtest`的文件夹,并在其中编写一个名为`CMakeLists.txt`的文件,指定gtest的相关配置,例如: ``` add_subdirectory(gtest) ``` 这将在`gtest`文件夹中编译生成名为`gtest`的可执行文件。 综上所述,使用CMakegtest进行编译和测试的步骤如下: 1. 在项目的根目录下创建`CMakeLists.txt`文件,并添加相关配置。 2. 在项目根目录下创建`gtest`文件夹,编写`CMakeLists.txt`文件,指定gtest的相关配置。 3. 使用上述命令创建build文件夹并进行编译。 希望对你有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [集成gtest进行单元测试之cmake应用](https://blog.csdn.net/OKCRoss/article/details/130866295)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ubuntu下vscode+cmake实现gtestcmake引入gtest,glog)](https://blog.csdn.net/NotANumber123/article/details/126246983)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值