当前位置: 首页 > news >正文

单元测试(UT,C++版)经验总结(gtest+gmock)

        最近做了一段测试工作,其中包括单元测试,编程语言是C++。这里提供一些基本知识总结,方便入门单元测试。

1.单元测试介绍

单元测试(Unit Testing, 简称UT)是软件测试的一种方法,目的是通过对单个软件组件(即单元)的验证,确保其按预期工作。对于C++程序开发者来说,单元测试是一项重要的质量保障手段,能够帮助开发者在代码开发过程中及时发现和修复问题。

单元测试的优点:

  • 提高代码质量:通过自动化的测试,能够有效捕捉到程序中的潜在缺陷。
  • 回归测试:随着代码的不断重构和修改,单元测试能够确保原有功能没有被破坏。
  • 文档化代码:良好的单元测试不仅是验证代码的工具,也充当了文档角色,帮助开发人员更容易理解代码的预期行为。
  • 减少调试时间:因为测试能够尽早发现问题,能够帮助开发者避免在较后阶段出现难以调试的问题。

单元测试的挑战:

  • 测试覆盖率:虽然单元测试能够有效发现许多问题,但并不是每个错误都能被检测到,因此测试覆盖率需要设计得足够高。
  • 维护性:随着项目规模的增大,单元测试本身也可能会变得非常庞大和复杂,维护起来可能会成为一个负担。

2.google test

        Google Test(gtest)是由Google开发的一个C++测试框架,用于编写和执行单元测试。它提供了许多功能,使得编写和执行单元测试变得更加简便和高效。gtest支持断言(assertion)、异常捕获、参数化测试等功能。

在项目中使用: 在Cmakelist里通过 find_package(GTest REQUIRED) 来引入Google Test库

头文件:

#include <gtest/gtest.h>

常用断言:

EXPECT_EQ(val1, val2):断言两个值相等。
EXPECT_NE(val1, val2):断言两个值不相等。
EXPECT_TRUE(expression):断言表达式为true。
EXPECT_FALSE(expression):断言表达式为false。
ASSERT_* 和 EXPECT_*:两者的区别在于ASSERT_*失败时会立即终止当前测试用例的执行,而EXPECT_*会继续执行。

参数化测试:

gtest支持参数化测试,允许使用不同的参数多次运行同一个测试逻辑。

class MyTest : public ::testing::TestWithParam<int> {};TEST_P(MyTest, TestWithParam) {EXPECT_EQ(GetParam(), 1);  // 断言传入的参数与1相等
}INSTANTIATE_TEST_SUITE_P(MyTests, MyTest, ::testing::Values(1, 2, 3));

3. goole mock

Google Mock(gmock)是Google推出的一个用于C++的模拟框架,用于为依赖的外部对象创建模拟(Mock)对象。在单元测试中,经常需要模拟外部依赖,以便测试目标函数的行为,而Google Mock正是提供了这种能力。

在项目中使用: 在Cmakelist里通过 find_package(GMock REQUIRED) 来引入Google Test库

头文件:

#include <gmock/gmock.h>

使用gmock时,我们通过模拟对象来替代真实的对象,避免依赖外部系统。以下是gmock的一些基本用法。

  1. 创建 Mock 类:通过继承testing::Mock,然后模拟所需的成员函数。

  • class MyClass {
    public:virtual int Multiply(int a, int b) {return a * b;}
    };class MockMyClass : public MyClass {
    public:MOCK_METHOD(int, Multiply, (int a, int b), (override));
    };
    
  • 2. 设置期望:使用EXPECT_CALL来设置期望,断言模拟对象的方法是否按预期被调用。

  • TEST(MockTest, MultiplyTest) {MockMyClass mock;EXPECT_CALL(mock, Multiply(2, 3)).WillOnce(testing::Return(6));  // 设置期望:Multiply(2, 3)返回6EXPECT_EQ(mock.Multiply(2, 3), 6);  // 断言返回值是否为6
    }
    
  • 3. 模拟行为:可以通过WillOnceWillRepeatedly指定模拟方法的返回值或行为。

  • EXPECT_CALL(mock, Multiply(testing::Gt(0), testing::Lt(10))).WillRepeatedly(testing::Return(42));  // 所有大于0且小于10的输入都会返回42
    
  • 4. 模拟void函数:对于返回类型为void的函数,使用MOCK_METHOD时,可以通过WillOnce模拟其行为。

    class MyClass {
    public:virtual void DoSomething() {// Do something}
    };class MockMyClass : public MyClass {
    public:MOCK_METHOD(void, DoSomething, (), (override));
    };TEST(MockTest, DoSomethingTest) {MockMyClass mock;EXPECT_CALL(mock, DoSomething()).Times(1);  // 期望DoSomething()被调用一次mock.DoSomething();  // 调用
    }
    

  • 5. 验证期望:gmock会根据EXPECT_CALL的期望来验证实际行为。如果期望的行为未被触发或被触发的次数不正确,gmock会报告错误。

  • 6. 匹配器(Matchers):gmock提供了强大的匹配器,能够对函数参数进行更灵活的验证。例如:

    • testing::Eq(val):匹配相等的值。
    • testing::Gt(val):匹配大于val的值。
    • testing::Lt(val):匹配小于val的值。

进阶使用:

  • 动作链式调用:通过WillOnceWillRepeatedly可以设置多个返回值。
  • Mock方法的调用顺序:可以通过InSequence来检查多个期望的调用顺序。
TEST(MockTest, CallOrderTest) {MockMyClass mock;{testing::InSequence seq;  // 保证调用顺序EXPECT_CALL(mock, Multiply(2, 3)).WillOnce(testing::Return(6));EXPECT_CALL(mock, Multiply(4, 5)).WillOnce(testing::Return(20));}mock.Multiply(2, 3);mock.Multiply(4, 5);
}

 

相关文章:

单元测试(UT,C++版)经验总结(gtest+gmock)

最近做了一段测试工作&#xff0c;其中包括单元测试&#xff0c;编程语言是C。这里提供一些基本知识总结&#xff0c;方便入门单元测试。 1.单元测试介绍 单元测试&#xff08;Unit Testing, 简称UT&#xff09;是软件测试的一种方法&#xff0c;目的是通过对单个软件组件&am…...

Mysql高级部分总结(二)

MySQL的内部日志 binlog记载的是update/delete/insert这样的SQL语句,而redo log记载的是物理修改的内容(xxxx页修改了xxx)。 binlog无论MySQL用什么引擎,都会有,而redo log是MySQL的InnoDB引擎所产生的。 redo log事务开始的时候,就开始记录每次的变更信息,而binlog是在…...

纠正一下网络管理

先找到那个hrStorageType 这里我的值是 后面的值.1.3.6.1.2.1.25.2.1.4代表磁盘 我只有2个盘 C盘和D盘 所以这里只有2个 你们有E盘F盘的话 这里会多 .1.3.6.1.2.1.25.2.1.2 代表内存 .1.3.6.1.2.1.25.2.1.2 前面是 hrStorageType.4 所以 这里面.4后缀是表示内存的 之前…...

homebrew,gem,cocoapod 换源,以及安装依赖

安装homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 再按照成功提示配置环境变量 ruby 更新ruby到最新 brew install ruby 如果安装了会自动升级 安装完成后根据提示配置环境变量 再执行命令使其生效 s…...

Java字符串的|分隔符转List实现方案

字符串处理 问题背景代码实现代码优化原因分析实现方案 注意事项异常处理Maven未识别异常 问题背景 在项目组对账流程中&#xff0c;接收对方系统的对账文件&#xff0c;数据以|为分隔符&#xff0c;读取文件内容&#xff0c;分条入库。 代码实现 Java中将字符串转给list&am…...

Kafka可视化工具 Offset Explorer (以前叫Kafka Tool)

数据的存储是基于 主题&#xff08;Topic&#xff09; 和 分区&#xff08;Partition&#xff09; 的 Kafka是一个高可靠性的分布式消息系统&#xff0c;广泛应用于大规模数据处理和实时, 为了更方便地管理和监控Kafka集群&#xff0c;开发人员和运维人员经常需要使用可视化工具…...

DeepWalk 原理详解

概述&#xff1a; DeepWalk 是一种流行的图嵌入方法&#xff0c;用于学习图结构数据中节点的低维表示。它通过将图的节点视作序列数据&#xff0c;利用自然语言处理中的技术&#xff08;类似于word2vec算法&#xff09;来捕捉节点间的关系&#xff0c;可以帮助我们理解和利用图…...

GitLab安装|备份数据|迁移数据及使用教程

作者&#xff1a; 宋发元 最后更新时间&#xff1a;2024-12-24 GitLab安装及使用教程 官方教程 https://docs.gitlab.com/ee/install/docker.html Docker安装GitLab 宿主机创建容器持久化目录卷 mkdir -p /docker/gitlab/{config,data,logs}拉取GitLab镜像 docker pull gi…...

嵌入式linux驱动框架 I2C系统驱动程序模型分析

引言&#xff1a;在嵌入式 Linux 系统中&#xff0c;I2C&#xff08;Inter-Integrated Circuit&#xff09;是一种常用的通信协议&#xff0c;用于连接低速设备&#xff08;如传感器、显示器、存储器等&#xff09;与主控制器。I2C 系统驱动程序模型通过层次化的设计&#xff0…...

深度学习实验十七 优化算法比较

目录 一、优化算法的实验设定 1.1 2D可视化实验&#xff08;被优化函数为&#xff09; 1.2 简单拟合实验 二、学习率调整 2.1 AdaGrad算法 2.2 RMSprop算法 三、梯度修正估计 3.1 动量法 3.2 Adam算法 四、被优化函数变为的2D可视化 五、不同优化器的3D可视化对比 …...

一个双非选手的秋招总结

个人bg介绍 25届双非本硕&#xff08;非杭电深大&#xff0c;垫底双非&#xff09;&#xff0c;两段实习经历&#xff0c;本科没学过Java&#xff0c;有c语言和408基础&#xff1b;2023年10月份中途转语言&#xff0c;Java速成选手。 战绩总结&#xff1a;实习秋招面试总论次…...

如何提高永磁电动机的节电效果

在现代工业和家庭应用中&#xff0c;永磁电动机因其优越的性能和节能特性&#xff0c;逐渐成为主流选择。随着能源日益紧缺和环境问题的日益严重&#xff0c;寻求高效的电动机节能方案显得尤为重要。 一、永磁电动机的基本原理 永磁电动机的核心是永磁体&#xff0c;这些永磁…...

在一个服务器上抓取 Docker 镜像并在另一个服务器上运行

要在一个服务器上抓取 Docker 镜像并在另一个服务器上运行&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1. 保存 Docker 镜像 在源服务器上&#xff0c;您可以使用 docker save 命令将 Docker 镜像保存为一个 tar 文件。例如&#xff0c;如果您的镜像名称是 face_det…...

开源轮子 - Logback 和 Slf4j

spring boot内置&#xff1a;Logback 文章目录 spring boot内置&#xff1a;Logback一&#xff1a;Logback强在哪&#xff1f;二&#xff1a;简单使用三&#xff1a;把 log4j 转成 logback四&#xff1a;日志门面SLF4J1&#xff1a;什么是SLF4J2&#xff1a;SLF4J 解决了什么痛…...

内部知识库的未来展望:技术融合与用户体验的双重升级

在当今数字化飞速发展的时代&#xff0c;企业内部知识库作为知识管理的关键载体&#xff0c;正站在变革的十字路口&#xff0c;即将迎来技术融合与用户体验双重升级的崭新时代&#xff0c;这一系列变化将深度重塑企业知识管理的格局。 一、技术融合&#xff1a;开启知识管理新…...

【Linux系列】Shell 命令:`echo ““ > img.sh`及其应用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【RAG实战】语言模型基础

语言模型赋予了计算机理解和生成人类语言的能力。它结合了统计学原理和深度神经网络技术&#xff0c;通过对大量的样本数据进行复杂的概率分布分析来学习语言结构的内在模式和相关性。具体地&#xff0c;语言模型可根据上下文中已出现的词序列&#xff0c;使用概率推断来预测接…...

【MySQL】7.0 入门学习(七)——MySQL基本指令:帮助、清除输入、查询等

1.0 help &#xff1f; 帮助指令&#xff0c;查询某个指令的解释、用法、说明等。详情参考博文&#xff1a; 【数据库】6.0 MySQL入门学习&#xff08;六&#xff09;——MySQL启动与停止、官方手册、文档查询 https://www.cnblogs.com/xiaofu007/p/10301005.html 2.0 在cmd命…...

我的 2024 年终总结

2024 年&#xff0c;我离开了待了两年的互联网公司&#xff0c;来到了一家聚焦教育机器人和激光切割机的公司&#xff0c;没错&#xff0c;是一家硬件公司&#xff0c;从未接触过的领域&#xff0c;但这还不是我今年最重要的里程碑事件 5 月份的时候&#xff0c;正式提出了离职…...

STM32CUBEMX+STM32H743ZIT6+IAP+UART在线升级初始化和代码解析

1、STM32H7带的ITCM&#xff0c;DTCM&#xff0c;AXI SRAM&#xff0c;SRAM1&#xff0c;SRAM2&#xff0c;SRAM3&#xff0c;SRAM4和备份SRAM五块。 其中&#xff0c; ①TCM区包括ITCM和DTCM&#xff0c;这两个是直连CPU的。 速率与CPU一致&#xff0c;最高能到480MHz。 DTCM地…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...