gtest测试框架

news2024/9/27 7:24:01

文章目录

  • 前言
  • 1 单元测试
  • 2 gtest安装
  • 3 gtest原理
  • 4 断言
    • 4.1 明确指定或失败
    • 4.2 布尔条件
    • 4.3 二元比较
    • 4.4 谓词断言
    • 4.5 死亡测试
  • 5 gtest使用
    • 5.1 测试函数
    • 5.2 测试类
    • 5.3 测试夹具
    • 5.4 类型参数化
    • 5.5 事件
  • 总结

前言

GoogleTest(GTest) 是谷歌开源的 C++ 单元测试框架。

1 单元测试

单元测试unit testing是指对软件中的最小可测试单元进行检查和验证,包括函数、类、模块、复杂交互逻辑等。gtest 中单元测试以单例模式实现。每个单元测试包含若干个测试套件test suite,测试套件是指一组功能相同的测试脚本或过程。每个测试套件包含多个测试案例test case,测试同一个功能的不同方向。
在这里插入图片描述
根据 gtest 官方文档,一个好的单元测试应该满足:

  • 独立、可重复:测试案例可单独执行,错误可重复发生。
  • 反映测试代码结构:功能完整,体现完备逻辑。对于关联功能,一个功能是否影响其他功能
  • 可移植、可复用:跨平台。
  • 尽可能多的出错信息:不会因为一次失败而停止,会继续测试下一个测试案例。一次测试发现多个错误。
  • 自动跟踪所有测试而无需枚举:向容器中添加
  • 测试高效:测试间重用资源,mock 模拟复杂交互

如何整体使用单元测试?

  • 每个类或功能块加上测试案例
  • test 目录加上所有的测试
  • 一个单元测试可能散落在多个文件

单元测试中的打桩,是指用来代替关联代码或者未实现代码的代码,即用桩函数代替原函数。打桩测试由 gtest 里的 gmock 来实现。

2 gtest安装

 # 下载
 git clone https://github.com/google/googletest.git
 # 安装
 cd googletest
 cmake CMakeLists.txt
 make
 sudo make install

源码文件中的 lib 库,包含 gtest 库和 gmock 库。

 libgtest.a  libgtest_main.a  libgmock.a  libgmock_main.a

当测试代码有 main 函数,使用不带 main 的静态库,否则使用带 main 的静态库。

 # 无 main 函数
 g++ sample.cc sample_unittest.cc -o sample -lgtest -lgtest_main -lpthread
 # 有 main 函数
 g++ gmock_output_test_.cc -o output -lgtest -lgmock -lpthread

若需要编写 main 函数,关键在于添加两个地方

 int main(int argc, char **argv) {
   
   // 1.定义 main 函数:初始化 gtest
   ::testing::InitGoogleTest(&argc, argv);
   // 2.定义 main 函数:开启全部测试
   return RUN_ALL_TESTS();
 }

3 gtest原理

GTest 测试底层原理

  • 创建单元测试类,单例模式实现,包含vector<TestSuite*>
  • 根据测试套件名,生成一个TestSuite 类实例,包含vector<TestInfo*>;
  • 根据测试案例名,生成一个Test_info类实例,继承父类 testing::Test
  • 将测试案例实例注册到测试套件中vector<TestSuite*>,测试套件类实例调用run方法执行测试

类的组织层次

 // 单元测试,单例模式实现
 class Impl {
   
     // 存储测试套件类实例
     vector<TestSuite*>;
 }// 测试套件
 class TestSuite {
   
     // 存储测试案例类实例
     vector<TestInfo*>;
     // 执行测试套件中的测试案例
     run();
 }// 测试案例
 class TestInfo {
   
     // 执行测试
     TestBody();
 };

4 断言

使用测试断言,通过断言其行为来测试类和函数。ASSERT_* 失败时会生成致命错误,并中止当前功能(但是他会执行测试套件中的下一个测试案例);EXPECT_失败时生成非致命错误,不会中止当前功能。通常选用EXPECT_

所有断言宏都支持输出流,经流输出的信息自动转换为utf-8,可利用这一特性输出详细错误信息

// 流后面可以使用中文,因为经流输出的信息会自动转换为utf-8
EXPECT_TRUE(my_condition) << "My condition is not true";

4.1 明确指定或失败

当测试案例中的条件太复杂,不能使用断言,那么自己写判断语句;自己返回成功或者失败;比如下面
在这里插入图片描述

4.2 布尔条件

 EXPECT_TRUE(condition)
 ASSERT_TRUE(condition)EXPECT_FALSE(condition)
 ASSERT_FALSE(condition)

4.3 二元比较

 // val1 = val2
 EXPECT_EQ( val1 , val2 )
 ASSERT_EQ( val1 , val2 )// val1 != val2,空指针使用 nullptr
 EXPECT_NE( val1 , val2 )
 ASSERT_NE( val1 , val2 )// val1 <= val2
 EXPECT_LT( val1 , val2 )
 ASSERT_LT( val1 , val2 )// val1 > val2
 EXPECT_GT( val1 , val2 )
 ASSERT_GT( val1 , val2 )// val1 >= val2
 EXPECT_GE( val1 , val2 )
 ASSERT_GE( val1 , val2 )

4.4 谓词断言

 EXPECT_PREDn( pred , val1, ..., valn ) \
 ASSERT_PREDn( pred , val1, ..., valn ) \

例如:测试阶乘函数,参数 1 个

EXPECT_PRED1(Factorial, 1)

说明:

  1. 谓词断言时,出错时会将参数打印出来,方便查看

4.5 死亡测试

用于测试程序是否以预期的方式崩溃。

EXPECT_DEATH(func, desc);

说明:

  1. 如果我们写了死亡测试用例,那么调用者读文档时,一看调用相关的参数会崩溃,这将会引起调用者的注意,从而使得它会做一些判断

5 gtest使用

5.1 测试函数

使用 TEST宏来定义测试案例。

 #include "sample1.h"
 #include <limits.h>
 #include "gtest/gtest.h"// 使用 TEST 宏定义测试案例 
 // #define TEST(test_suite_name,test_name)
 // 测试阶乘:负数
 TEST(FactorialTest, Negative) {
   
   // 断言:预期相等 EXPECT_EQ(expected, actual),后面同理
   EXPECT_EQ(1, Factorial(-5));
   EXPECT_EQ(1, Factorial(-1));
   EXPECT_GT(Factorial(-10), 0);
 }// 测试阶乘:0
 TEST(FactorialTest, Zero) {
    EXPECT_EQ(1, Factorial(0)); }// 测试阶乘:正数
 TEST(</

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1429782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redis存储对象的过期设置在实际项目中的运用案例展示

redis存储对象的过期设置在实际项目中的运用案例展示&#xff01;经过前面的学习&#xff0c;我们已经基本上初步掌握了redis数据库存储对象的过期时间是如何设置的了。下面给大家展示一个具体的实际开发项目中用到业务场景。 在项目化生寺小程序游戏开发中&#xff0c;有道具&…

什么是TCP粘包和半包问题?如何解决?

什么是TCP粘包问题&#xff1f;如何解决&#xff1f; TCP粘包和半包是数据传输中比较常见的问题。所谓的粘包问题就是指在数据传输的时候&#xff0c;在一条消息中读取到了另一条消息的部分数据&#xff0c;如下图&#xff1a; 半包是指接收端只收到了部分的数据&#xff0c;而…

【C语言/基础梳理/期末复习】动态内存管理(附思维导图)

目录 一、为什么要有动态内存分配 &#xff08;1&#xff09;我们已经掌握的内存方式的特点 &#xff08;2&#xff09;需求 二、malloc和free 2.1.malloc 2.1.1函数原型 2.1.2函数使用 2.1.3应用示例​编辑 2.2free 2.2.1函数原型 2.2.2函数使用 三、calloc和reallo…

算法练习-左叶子之和(思路+流程图+代码)

难度参考 难度&#xff1a;中等 分类&#xff1a;二叉树 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。且所在课程未提供测试平台&#xff0c;故实现代码主要为自行测试的那种&#xff0c;以下内容均为个人笔记&#xff0c;旨…

rust gui开发框架选择

作为一个系统编程强大语言&#xff0c;怎么能少得了图形界面的开发 实际上写这篇前我也不知道&#xff0c;于是我问了ai大模型&#xff0c;文心3.5和chatgpt4.0 答案实际上不能满意&#xff0c;最后我做了下筛选 参考博文&#xff1a; rust开发环境配置&#xff1a;链接 一、…

Loadbalancer如何优雅分担服务负荷

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Loadbalancer如何优雅分担服务负荷 前言Loadbalancer基础&#xff1a;数字世界的分配大师1. 分发请求&#xff1a;2. 健康检查&#xff1a;3. 会话保持&#xff1a;4. 可伸缩性&#xff1a;5. 负载均衡…

数据结构—基础知识:哈夫曼编码

文章目录 数据结构—基础知识&#xff1a;哈夫曼编码哈夫曼编码的主要思想有关编码的概念哈夫曼编码满足两个性质&#xff1a; 数据结构—基础知识&#xff1a;哈夫曼编码 哈夫曼编码的主要思想 在进行数据压缩时&#xff0c;为了使压缩后的数据文件尽可能短&#xff0c;可采…

二手电脑配置给你不一样的成就感

回顾从小到大使用电脑、组装电脑到开发软硬件的经历&#xff0c;总是对二手电脑有着不一样的情感&#xff0c;近五年买过八台新电脑&#xff0c;一台是图像处理培训买的笔记本&#xff0c;一台是小孩上课的台式机&#xff0c;一台是老人的集成办卡电脑&#xff0c;还有一些工作…

Vue3_基础使用_2

这节主要介绍&#xff1a;标签和组件的ref属性&#xff0c;父子组件间的传递值&#xff0c;ts的接口定义&#xff0c;vue3的生命周期 1.标签的ref属性。 1.1ref属性就是给标签打标识用的&#xff0c;相当于html的id&#xff0c;但是在vue3中用id可能会乱&#xff0c;下面是ref…

跟着cherno手搓游戏引擎【18】抽象Shader、项目小修改

抽象&#xff1a; Shader.h: #pragma once #include <string>namespace YOTO {class Shader {public:virtual~Shader()default;virtual void Bind()const0;virtual void UnBind()const0;static Shader* Create(const std::string& vertexSrc, const std::string&am…

软考高项-机考相关介绍论文写作基础介绍

机考相关 初、中级(信息处理技术员除外)资格:基础知识和应用技术2个科目连考,基础知识科目最短作答时长90分钟,最长作答时长120分钟,2个科目作答总时长240分钟,考试结束前60分钟可交卷离场 历年论文考题

java数据结构与算法刷题-----LeetCode15. 三数之和

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 解题思路 和LeetCode1.两数之和一样&#xff0c;但是这道题边界条件更多。…

Flutter 各种Demo效果合集

Flutter 各种Demo实现效果&#xff1a; github&#xff1a;GitHub - PangHaHa12138/FlutterDemo: Flutter 各种Demo效果合集 1&#xff1a;2种 仿朋友圈 效果,顶部拉伸 和 不拉伸 2&#xff1a;仿抖音上下滑动视频播放 3&#xff1a;视频直播&#xff08;使用的电视台的m3u…

云计算基础(云计算概述)

目录 一、云计算概述 1.1 云计算的概念 1.1.1 云计算解决的问题 1.1.2 云计算的概念 1.1.3 云计算的组成 1.2 云计算主要特征 1.2.1 按需自助服务 1.2.2 泛在接入 1.2.3 资源池化 1.2.4 快速伸缩性 1.2.5 服务可度量 1.3 云计算服务模式 1.3.1 软件即服务(Softwar…

C#验证字符串是否包含汉字:用正则表达式 vs 用ASCII码 vs 用汉字的 Unicode 编码

目录 一、使用的方法 1.使用正则表达式验证字符串 2.使用正则表达式验证字符 3.用ASCII码判断 4.用汉字的 Unicode 编码范围判断 二、实例 1.源码 2.生成效果 验证一个字符串是否是纯汉字或者包含有汉字的前提&#xff0c;是VS编辑器的默认编码格式设置为&#xff1a;选…

Vite与Webpack打包内存溢出问题优雅处理方式

Vite与Webpack打包内存溢出问题处理 文章目录 Vite与Webpack打包内存溢出问题处理1. Vite1. 打包错误提示2. 命令行方式解决3. 配置环境变量方式解决1. 设置变量2. 配置系统的环境变量 2. Webpack1. 打包错误提示2. 命令行方式解决3. 配置环境变量方式解决1. 设置变量2. 配置系…

Llama2大模型开源,大模型的Android时代来了?

就昨天凌晨,微软和Meta宣布Llama2大模型开源且进一步放开商用,一下朋友圈刷屏。要知道,开源界最强大的模型就是过去Meta开源的Llama,而现在Llama2更强大,又开放商用,更有微软大模型霸主企业撑腰(微软既投资大模型界的IOS——ChatGPT,又联合发布大模型的Android——Llam…

旧衣物回收小程序开发,互联网模式下的营收有多大?

在当下快节奏的生活中&#xff0c;人们不仅生活水平在提高&#xff0c;消费水平也在逐渐提高&#xff0c;从而导致了闲置衣物的增加。为了减少浪费&#xff0c;旧衣服回收行业受到了大众的广泛关注&#xff0c;成为循环利用的一大方式。 当然&#xff0c;在当下网络时代&#…

Docker 阿里云镜像仓库CR使用实践

一、使用容器镜像&#xff0c;查看镜像&#xff0c;创建&#xff0c;推送&#xff0c;拉取阿里云镜像 CR镜像管理&#xff08;阿里云容器镜像服务&#xff08;Container Registry&#xff09;&#xff09; 登录实例 未创建的镜像名称也可以push、docker的私有仓库需要提起创建…

C语言——深入理解指针(1)

目录 1.内存和地址 a 内存的理解 b 如何理解编址 2.指针变量和地址 a 取地址操作符 b 指针变量 c 解引用操作符 d 指针变量的大小 1.内存和地址 a 内存的理解 假想这样一个场景&#xff0c;你的朋友找你玩&#xff0c;到了你家小区&#xff0c;如何让她迅速的找到…