使用gtest做单元测试

2023-11-05

使用gtest做单元测试


gtest是一个跨平台的(Liunx、Mac OS X、Windows 、Cygwin 、Windows CE and Symbian ) C++单元测试框架,由google公司发布。gtest是为在不同平台上为编写C++测试而生成的。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等

1.用gtest写测试工程的大致流程

配置gtest头文件及库

下载gtest源码:

Releases · google/googletest (github.com)

一般选择最新版应该就没啥问题

放到本地编译,这里假设下载的是1.8.0版本

tar -zxvf googletest-release-1.8.0.tar.gz 
cd googletest-release-1.8.0/ 
mkdir build 
cd build 
cmake .. 
# 编译 
make 
# 安装 
make install

编译完之后,把googletest/include下的gtest头文件拷贝放到自己测试工程的include目录下。

image-20220529110417505

然后把编译出来的静态库(在build/googlemock/gtest下,分别叫libgtest.a和libgtest_main.a),放到自己测试工程下的lib文件夹下。我本地的lib目录如下,其中gmock是用来打桩的,打桩的意思是测试中一个函数还没有实现,然后在需要调用该函数的地方设置一个返回规则,这个加不加都无所谓。

image-20220529110216051

然后在CMakeLists.txt加入相应的配置信息

# 包含头文件的路径 
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
# 设置库文件的生成路径
set(LIBRARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib")

# 链接依赖的库: gtest库,pthread库 
target_link_libraries(Test目标文件 ${LIBRARY_PATH}/gtest/libgtest.a) 
target_link_libraries(Test目标文件 ${LIBRARY_PATH}/gtest/libgtest_main.a) 
target_link_libraries(Test目标文件 pthread)

然后在测试工程源文件中添加对gtest头文件,就可以使用gtest的一系列宏定义来写单元测试函数了

// Test.cpp 
#include <gtest/gtest.h> 
#include "待测试代码头文件.h" /* 待测试的业务代码头文件 */ 

/* 使用TEST宏定义测试名、用例名 */ 
TEST(Module1, function1) 
{ 
    int res = function1(...); /* 调用待测试函数 */ 
    ... 
    EXPECT_EQ(res, 1); 
    /* 比较返回和期望值 */ 
}

最后写上运行所有测试用例,就可以跑测试了。

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

以上都写得很简单,但大概流程就是,拉取gtest源码进行编译,生成gtest静态库,然后把gtest的头文件和库文件加入测试工程中,这样就可以调用gtest了。在自己测试工程中使用TEST或者TEST_F宏定义结合断言来写单元测试函数,最后运行RUN_ALL_TESTS()来运行所有测试用例。当然,CMakeLists.txt中也是必须添加相关路径引用设置的。

gtest的相关概念

TEST与TEST_F

  • TEST(test_case_name, test_name)

创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用提供的断言来进行检查。

  • TEST_F(test_fixture,test_name)

多个测试场景需要相同数据配置的情况,用 TEST_F 。TEST_F test fixture,测试夹具,测试套,承担了一个注册的功能。

断言

gtest中断言的宏可以分为两类:一类是ASSERT宏,另一类就是EXPECT宏了。

1、ASSERT_系列:如果当前点检测失败则退出当前函数

2、EXPECT_系列:如果当前点检测失败则继续往下执行

如果你对自动输出的错误信息不满意的话,也是可以通过operator<<能够在失败的时候打印日志,将一些自定义的信息输出。

比如:

ASSERT_TRUE(Abs(1) == 1) << "Abs(1)=1";

这样在判断不通过时会有后面打印"Abs(1)=1"。

ASSERT_系列:

bool值检查

1、 ASSERT_TRUE(参数),期待结果是true

2、ASSERT_FALSE(参数),期待结果是false

数值型数据检查

3、ASSERT_EQ(参数1,参数2),传入的是需要比较的两个数 equal

4、ASSERT_NE(参数1,参数2),not equal,不等于才返回true

5、ASSERT_LT(参数1,参数2),less than,小于才返回true

6、ASSERT_GT(参数1,参数2),greater than,大于才返回true

7、ASSERT_LE(参数1,参数2),less equal,小于等于才返回true

8、ASSERT_GE(参数1,参数2),greater equal,大于等于才返回true

字符串检查

9、ASSERT_STREQ(expected_str, actual_str),两个C风格的字符串相等才正确返回

10、ASSERT_STRNE(str1, str2),两个C风格的字符串不相等时才正确返回

11、ASSERT_STRCASEEQ(expected_str, actual_str)

12、ASSERT_STRCASENE(str1, str2)

EXPECT_系列,也是具有类似的宏结构的

事件机制

我理解的事件机制是,每个TestSuite事件是某个TestSuite下的所有测试可能需要有一些相同条件,那么在每个TestSuite前运行一遍的函数或者设置,会在这个TestSuite里的所有TestCase里都是一样的,然后每个TestCase运行前可能也有些需要预先运行的函数或者设置,这个需要在TestCase事件里设置。详细解释如下:

“事件” 本质是框架给你提供了一个机会, 让你能在这样的几个机会来执行你自己定制的代码, 来给测试用例准备/清理数据。gtest提供了多种事件机制,总结一下gtest的事件一共有三种:

1、TestSuite事件

需要写一个类,继承testing::Test,然后实现两个静态方法:SetUpTestCase 方法在第一个TestCase之前执行;TearDownTestCase方法在最后一个TestCase之后执行。

2、TestCase事件

是挂在每个案例执行前后的,需要实现的是SetUp方法和TearDown方法。SetUp方法在每个TestCase之前执行;TearDown方法在每个TestCase之后执行。

3、全局事件

要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。SetUp方法在所有案例执行前执行;TearDown方法在所有案例执行后执行。

例如全局事件可以按照下列方式来使用:

除了要继承testing::Environment类,还要定义一个该全局环境的一个对象并将该对象添加到全局环境测试中去。

TetsSuite事件和TestCase事件如下设置:

class TestMap:public testing::Test
{
public:
//TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后。
static void SetUpTestCase()
{
cout<<"SetUpTestCase"<<endl;
}
static void TearDownTestCase()
{
cout<<"TearDownTestCase"<<endl;
}
/*TestCase级别的,每个TestCase前后*/
virtual void SetUp() //TEST跑之前会执行SetUp
{
cout<<"SetUp"<<endl;
}
virtual void TearDown() //TEST跑完之后会执行TearDown
{
cout<<"TearDown"<<endl;
}
};
TEST_F(TestMap,Find) //此时使用的是TEST_F宏
{
map<int,int>::iterator it=test_map.find(1);
ASSERT_NE(it,test_map.end());
}
TEST_F(TestMap,Size)
{
ASSERT_EQ(test_map.size(),5);
}
int main(int argc,char *argv[])
{
testing::InitGoogleTest(&argc, argv);//将命令行参数传递给gtest
return RUN_ALL_TESTS(); //RUN_ALL_TESTS()运行所有测试案例
}

即一般在一个头文件里引用gtest和待测试的代码头文件,然后写一个类继承testing::Test,实现里面的SetUp和

TearDown等函数,最后在测试cpp文件里使用TEST_F()来写单元测试,这时TestCase必须是刚才写的类名。

参考

gtest的介绍和使用-测试 (uml.org.cn)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用gtest做单元测试 的相关文章

随机推荐

  • Unity3D获得Android和iOS设备的唯一标识

    前言 android为mac地址 ios为advertisingIdentifier 函数都比较简单 网上也搜得到 我也就不多说了 主要是对于我们没做过安卓和IOS开发的人来说 整合进工程有各种的问题 我也就直接上网盘了点击打开链接 代码包
  • 【ant design vue】图片上传(一)

    官网是这样的 action 官网说不管是否使用都不能空着 但是实际上 在我的项目中是没有使用到的 我们是动态上传到后端 然后后端返回一个图片地址给我们显示在前台 代码如下 accept 是限制图片上传类型 customRequest 是自定
  • android edittext 数字正则,一个带有正则匹配的EditText

    先上效果 说明 图中的EditText能够在失去焦点后验证输入框中的文本是否与正则表达式匹配 这里我设置的是5位整数 d 5 当输入110时 不匹配 边框变红并抖动 文本清除 gif中白色文本是因为录制的问题 实际文本已清除 输入12306
  • windows10 powershell窗口输出卡住(看这篇就够了)

    问题原因 cmd窗口开启了快速编辑模式 当点击窗口时运行的进程会被暂停直至点击回车按钮 解决方案 取消勾选快速编辑模式 1 第一步 右键标题栏 选择 属性 第二步 选择 编辑选项 区域 取消 快速编辑模式 的选项 如图所示
  • Linux安装mysql5.7.26 --(傻瓜版3分钟搞定)

    前言 在这之前的一天时间里 我全网搜mysql 的各种安装方式 还有版本不同带来的问题 会发现在 Mac 或者 在linux上安装5 7 一下版本时 出现的问题会少很多 尤其是 拿着 dmg文件在Mac 安装 就是1分钟的事 但是在linu
  • Qt 中实现阴影窗口

    阴影窗口的实现方法一般有三种 方法一是 在窗口的构造函数中设置窗口的属性为 setAttribute Qt WA TranslucentBackground 从而保证窗口不被绘制的部分透明化 接着重写绘制函数paintEvent 其代码示例
  • 变量、作用域与内存

    目录 原始值与引用值 动态属性 复制值 传递参数 确定类型 执行上下文与作用域 作用域链增强 变量声明 1 使用var 的函数作用域声明 2 使用let 的块级作用域声明 3 使用const 的常量声明 标识符查找 垃圾回收 标记清理 最常
  • MPI测试程序

    include
  • mysql cmd命令行 创建数据库 表 基础语句

    一 连接MYSQL 格式 mysql h主机地址 u用户名 p用户密码 1 连接到本机上的MYSQL 首先打开DOS窗口 然后进入目录mysql bin 再键入命令mysql u root p 回车后提示你输密码 注意用户名前可以有空格也可
  • A*寻路算法 lua

    function InitMap self AMap for i 1 10 do self AMap i for j 1 10 do local map map x i map y j map g 999 map h 0 map f 0 m
  • 如何运行一个CFDEM tutorial case

    新手入门 万里长征第一步 安装完CFDEM后 我们知道有很多tutorial可以教我们怎么设置合理的参数 很多tutorial case里都有写好的Allrun脚本 最简单的方法就是运行Allrun脚本走一遍流程 准备工作 复制随便一个tu
  • 当里个当,免费的HTML5连载来了《HTML5网页开发实例详解》连载(一)

    读懂 HTML5网页开发实例详解 这本书 你还在用Flash嘛 帮主早不用了 乔布斯生前在公开信 Flash之我见 中预言 像HTML 5这样在移动时代中创立的新标准 将会在移动设备上获得胜利 国际巨头Google 苹果等都支持HTML 5
  • IDEA写爬虫,配jsoup

    环境变量配了 jdk的lib目录下也加了jsoup的jar包 返回IDEA还是没有 点击左上角的File进Project Setting SDKs 选择自己的jdk文件 在右侧点击 把jar包导进来
  • K8S 安装步骤

    K8S 安装步骤 一 为每台机器安装docker 1 安装docker 1 1 卸载旧版本 sudo yum remove docker docker client docker client latest docker common do
  • 【游戏开发】[用代码创建unity5.X的动画状态机]

    不废话 上代码 可能有的人 会质疑 这不是editor的功能吗 是的 但是这个允许在运行时候使用 你们跟一下代码看看继承于哪里就知道了 using UnityEngine using System Collections using Sys
  • JAVA-时间日期格式转换

    第一种方式 获取当前时间然后按照指定格式转换成String类型 DateFormat dateFormat new SimpleDateFormat yyyy MM dd HH mm ss Calendar cal Calendar get
  • 【Shell牛客刷题系列】SHELL31 netstat练习3-输出每个IP的连接数

    该系列是基于牛客Shell题库 针对具体题目进行查漏补缺 学习相应的命令 刷题链接 牛客题霸 Shell篇 该系列文章都放到专栏下 专栏链接为 专栏 Shell 欢迎关注专栏 本文知识预告 本文复习了awk grep sort uniq命令
  • DEiT实战:使用DEiT实现图像分类任务(二)

    文章目录 训练 导入项目使用的库 设置随机因子 设置全局参数 图像预处理与增强 读取数据 设置模型 train py train dist py 定义训练和验证函数 训练函数 验证函数 调用训练和验证方法 运行以及结果查看 测试 完整的代码
  • win10 git bash 设置别名

    使用git挺久时间 每次输入需要敲入长命令已感费劲 zshell git 有不少别名 可以提高输入效率 从而寻找windows下设置 git bash 别名的方法 环境 git v2 22 0 win10 方法1 通过 profile 文件
  • 使用gtest做单元测试

    使用gtest做单元测试 文章目录 使用gtest做单元测试 1 用gtest写测试工程的大致流程 配置gtest头文件及库 gtest的相关概念 TEST与TEST F 断言 事件机制 参考 gtest是一个跨平台的 Liunx Mac