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

玩转单元测试之gtest

引言

程序开发的时候,往往需要编写一些测试样例来完成功能测试,以保证自己的代码在功能上符合预期,能考虑到一些异常边界问题等等。

gtest快速入门

1.引入gtest

# 使用的是1.10版本,其他版本可根据需要选择
git clone -b v1.10.x https://github.com/google/googletest.git
cd googletest
mkdir build && cd build
cmake .. && make -j4
sudo make install
sudo ldconfig

2.编写第一个单测

2.1 待测试文件

#ifndef __HELLO_H__
#define __HELLO_H__#include <iostream>
#include <string>class Animal {
public:Animal(std::string name) : _name(name){}virtual ~Animal() {}virtual bool eat(const std::string& food) = 0;private:std::string _name;
};class Tigger : public Animal {
public:Tigger() : Animal("tigger"){}bool eat(const std::string& food) override{if (food == "meat") {return true;}return false;}
};class Horse : public Animal {
public:Horse() : Animal("Horse"){}bool eat(const std::string& food) override{if (food == "grass") {return true;}return false;}
};
#endif

2.2 单测文件

#include "hello.h"
#include "gtest/gtest.h"using namespace ::testing;namespace {
TEST(TestTigger, CaseEat) 
{Animal *tigger = new Tigger();bool ret = tigger->eat("meat");EXPECT_TRUE(ret);ret = tigger->eat("grass");EXPECT_FALSE(ret);delete tigger;
}TEST(TestHorse, CaseEat)
{Animal *horse = new Horse();bool ret = horse->eat("grass");EXPECT_TRUE(ret);ret = horse->eat("meat");EXPECT_FALSE(ret);delete horse;
}
}

2.3 makefile文件

CXX = g++
CXXFLAGS = -Wall
LIBES = -lgtest -lgtest_main -lpthread
LPATH = -L/tools/googletest/1.11.0/build/lib  # 替换成自己lib路径
HPATH = -I/tools/googletest/1.11.0/googletest/include/ # 替换成自己的include路径UTEST_OBJD = hello_unit_testhello_unit_test:hello_unit_test.cpp${CXX} -o $@ $+ -I ../ ${HPATH} ${CXXFLAGS} ${LIBES} ${LPATH}clean:rm -rf *_unit_test

make && ./hello_unit_test 编译并执行单测程序,执行结果如下:
在这里插入图片描述

gtest常用宏

1. 各种断言

1.1 Bool断言

致命断言非致命断言含义
ASSERT_TRUE(val)EXPECT_TRUE(val)val == true
ASSERT_FALSE(val)EXPECT_FALSE(val)val == false

1.2 二元值断言(比较大小)

致命断言非致命断言含义
ASSERT_EQ(a, b)EXPECT_EQ(a, b)a == b
ASSERT_NE(a, b)EXPECT_NE(a, b)a != b
ASSERT_LT(a, b)EXPECT_LT(a, b)a < b
ASSERT_LE(a, b)EXPECT_LE(a, b)a <= b
ASSERT_GT(a, b)EXPECT_GT(a, b)a > b
ASSERT_GE(a, b)EXPECT_GE(a, b)a >= b

1.3 字符串断言(字符串比较)

致命断言非致命断言含义
ASSERT_STREQ(a, b)EXPECT_STREQ(a, b)a == b
ASSERT_STRNE(a, b)EXPECT_STRNE(a, b)a != b
ASSERT_STRCASEEQ(a, b)EXPECT_STRCASEEQ(a, b)a == b 忽略大小写
ASSERT_STRCASENE(a, b)EXPECT_STRCASENE(a, b)a != b 忽略大小写

2. TEST、TEST_F和TEST_P

2.1 TEST

TEST是最基本的构造测试case的宏,基本用法:

TEST(param1, prama2)
{
/*测试代码*/
}
  • 参数1:用例名,一般由待测试的类名或函数名组成,如TestAnimal
  • 参数2:测试名,代表测试含义,如CaseEat
  • 测试结果将以"用例名.测试名"来区分不同测试case

2.2 TEST_F

TEST_F和TEST的不同之处在于,其可以使用到初始化函数(SetUp)和一个清理函数(TearDown)。基本用法如下:

class TestAnimal : public ::testing::Test {
protected:void SetUp() override{// 成员变量初始化tigger = new Tigger();}void TearDown() override{// 资源清理、释放delete tigger;tigger = NULL;}
protected:Animal *tigger;
};TEST_F(TestAnimal, caseEatMeat)
{	// 执行之前调用SetUp进行初始化EXPECT_TRUE(tigger->eat("meat"));// case退出时调用TearDown进行释放
}TEST_F(TestAnimal, caseEatGrass)
{// 执行之前调用SetUp进行初始化EXPECT_FALSE(tigger->eat("grass"));// case退出时调用TearDown进行释放
}
  • 创建一个继承testing::Test的测试类TestAnimal,并在该类中声明成员变量,做好初始化和清理操作
  • TEST_F宏
    • 参数1:同测试类名(TestAnimal )
    • 参数2:测试名,代表测试含义
  • 每一个测试case都是相互独立的,当每个case需要共同使用某个变量时,可以将该变量放在测试类中,每执行一个TEST_F宏构造的case,都会调用一次SetUp和TearDown,因此case之间对变量的操作不会相互影响

2.3 TEST_P

针对某个待测试的方法,当你需要测试不同的输入,但又不想每个case都写一遍时,就可以使用到TEST_P宏,基本使用如下:

// 多个参数时,使用结构体更方便
struct MyParams {std::string food;// other params
};
class TestAnimal : public ::testing::Test, public ::testing::WithParamInterface<MyParams>
{
protected:void SetUp() override{// 成员变量初始化tigger = new Tigger();}void TearDown() override{// 资源清理、释放delete tigger;tigger = NULL;}
protected:Animal *tigger;
};TEST_P(TestAnimal, caseEat) 
{std::string food = GetParam().food; // 获取参数ASSERT_FALSE(tigger->eat(food));
}// 构造不同的测试样例
INSTANTIATE_TEST_SUITE_P(TestCaseEatParams, TestAnimal, ::testing::Values(MyParams{"grass"},MyParams{"leafs"}
));
  • 和TEST_F有相似的功能,使用SetUp、TearDown进行初始化和清理,创建一个继承testing::Test、testing::WithParamInterface的测试类,其中WithParamInterface是一个模板类,用来关联测试参数。
  • TEST_P宏
    • 参数1:测试类名
    • 参数2:测试名,代表测试含义
  • INSTANTIATE_TEST_SUITE_P宏
    • 参数1:能表明测试含义即可
    • 参数2:测试类名
    • 参数3:不同测试样例集合
  • 执行结果如下:
    在这里插入图片描述

总结

  • 好记性不如烂笔头,最近在写单元测试,于是就有了这篇文章。
  • 通过学习gtest的基本语法,已经可以应对一部分测试场景了,然而还有一些场景只通过gtest是无法完成的,比如,在我们的代码中有许多并不是我们自己设计的接口,可能是外部依赖,也可能来自于其他模块,我们没办法设计一个合适的case来让这些接口返回给我们一个预期值,那我们该怎么办呢?于是gmock由此诞生,这个在下一篇中会进行深入学习,篇名我已经想好了(玩转单元测试之GMock)

相关文章:

玩转单元测试之gtest

引言 程序开发的时候&#xff0c;往往需要编写一些测试样例来完成功能测试&#xff0c;以保证自己的代码在功能上符合预期&#xff0c;能考虑到一些异常边界问题等等。 gtest快速入门 1.引入gtest # 使用的是1.10版本&#xff0c;其他版本可根据需要选择 git clone -b v1.1…...

Tomcat 一次请求的生命周期

在使用 Tomcat 的时候&#xff0c;我们只需要在 Servlet 实现类中写我们的业务逻辑代码即可&#xff0c;不需要管 Socket 连接、协议处理要怎么实现&#xff0c;因为这部分作为不经常变动的部分&#xff0c;被封装到了 Tomcat 中&#xff0c;程序员只需要引入 Tomcat 中即可&am…...

spring cloud gateway中配置uri

gateway中配置uri配置有三种方式: websocket方式&#xff1a;uri: ws://localhost:9000http方式: uri: http://localhost:8130/lb注册中心配置方式&#xff08;注册的服务名称&#xff09;: uri: lb://monitor-ms gateway的lb方式识别的服务名称命名规则&#xff1a; "[…...

使用NAudio录制wav音频

NAudio NAudio官网 环境 Unity2019.4.34f1c1 Window10 NAudio 1.10 .Net 3.5 录制音频 WaveInEvent类可录制音频 StartRecording方法 启用录制StopRecording方法 停止录制DataAvailable 录制中回调RecordingStopped 录制结束回调 WaveFileWriter类可存储音频 Write方法…...

数据结构之动态内存管理机制

目录 数据结构之动态内存管理机制 占用块和空闲块 系统的内存管理 可利用空间表 分配存储空间的方式 空间分配与回收过程产生的问题 边界标识法管理动态内存 分配算法 回收算法 伙伴系统管理动态内存 可利用空间表中结点构成 分配算法 回收算法 总结 无用单元收…...

【汇编语言】栈及栈操作的实现

文章目录 栈结构栈操作栈的小结 栈结构 栈是一种只能在一端插入或删除的数据结构&#xff1b;栈有两个基本的操作&#xff1a;入栈和出栈&#xff1b; 入栈&#xff1a;将一个新的元素放到栈顶&#xff1b;出栈&#xff1a;从栈顶取出一个元素&#xff1b; 栈的操作规则&#…...

【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用

【JavaEE】Spring AOP&#xff08;1&#xff09; 文章目录 【JavaEE】Spring AOP&#xff08;1&#xff09;1. Spring AOP 是什么1.1 AOP 与 Spring AOP1.2 没有AOP的世界是怎样的1.3 AOP是什么 2. Spring AOP 框架的学习2.1 AOP的组成2.1.1 Aspect 切面2.1.2 Pointcut 切点2.1…...

SpringBoot+微信小程序奶茶在线点单小程序系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBoot微信小程序框架开发的奶茶在线点单小程序系统。首先&#xff0c;这是一个前后端分离的项目&#xff…...

【支付宝小程序】开发基础--文件结构教程

&#x1f996;我是Sam9029&#xff0c;一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 &#x1f431;‍&#x1f409;&#x1f431;‍&#x1f409;恭喜你&#xff0c;若此文你认为写的不错&#xff0c;不要吝啬你的赞扬&#xff0c;求收…...

LLM 生成式配置的推理参数温度 top k tokens等 Generative configuration inference parameters

在这个视频中&#xff0c;你将了解一些方法和相关的配置参数&#xff0c;这些参数可以用来影响模型在下一个词生成时的最终决策方式。如果你在Hugging Face网站或AWS的游乐场中使用过LLMs&#xff0c;你可能已经看到了这些控制选项&#xff0c;用来调整LLM的行为。每个模型都暴…...

npm的镜像源和代理的查看和修改

一、镜像源 查询当前镜像源 npm get registry 设置为淘宝镜像 npm config set registry http://registry.npm.taobao.org/ 设置回默认的官方镜像 npm config set registry https://registry.npmjs.org/ 设置electron为淘宝镜像 npm config set ELECTRON_MIRROR "h…...

IP库新增经过实践的Verilog 库

网上严重缺乏实用的 Verilog 设计。Project F 库是尝试让 FPGA 初学者变得更好部分。 设计包括 Clock- 时钟生成 (PLL) 和域交叉Display - 显示时序、帧缓冲区、DVI/HDMI 输出Essential- 适用于多种设计的便捷模块Graphics- 绘制线条和形状Maths- 除法、LFSR、平方根、正弦....…...

SLAM-VIO视觉惯性里程计

SLAM 文章目录 SLAM前言IMU与视觉比较单目视觉缺陷&#xff1a;融合IMU优势&#xff1a;相机-IMU标定松耦合紧耦合基于滤波的融合方案&#xff1a;基于优化的融合方案&#xff1a; 前言 VIO&#xff08;visual-inertial odometry&#xff09;即视觉惯性里程计&#xff0c;有时…...

分布式 RPC 框架入门

分布式 RPC 框架入门 警告 torch.distributed.rpc 程序包是实验性的&#xff0c;随时可能更改。 它还需要 PyTorch 1.4.0才能运行&#xff0c;因为这是第一个支持 RPC 的版本。 本教程使用两个简单的示例来演示如何使用 torch.distributed.rpc 软件包构建分布式训练&#xf…...

Spring boot与Spring cloud 之间的关系

Spring boot与Spring cloud 之间的关系 Spring boot 是 Spring 的一套快速配置脚手架&#xff0c;可以基于spring boot 快速开发单个微服务&#xff0c;Spring Boot&#xff0c;看名字就知道是Spring的引导&#xff0c;就是用于启动Spring的&#xff0c;使得Spring的学习和使用…...

报名开启 | HarmonyOS第一课“营”在暑期系列直播

<HarmonyOS第一课>2023年再次启航&#xff01; 特邀HarmonyOS布道师云集华为开发者联盟直播间 聚焦HarmonyOS 4版本新特性 邀您一同学习赢好礼&#xff01; 你准备好了吗&#xff1f; ↓↓↓预约报名↓↓↓ 点击关注了解更多资讯&#xff0c;报名学习...

Apache DolphinScheduler 支持使用 OceanBase 作为元数据库啦!

DolphinScheduler是一个开源的分布式任务调度系统&#xff0c;拥有分布式架构、多任务类型、可视化操作、分布式调度和高可用等特性&#xff0c;适用于大规模分布式任务调度的场景。目前DolphinScheduler支持的元数据库有Mysql、PostgreSQL、H2&#xff0c;如果在业务中需要更好…...

matlab使用教程(17)—广度优先和深度优先搜索

1.可视化广度优先搜索和深度优先搜索 此示例说明如何定义这样的函数&#xff1a;该函数通过突出显示图的节点和边来显示 bfsearch 和 dfsearch 的可视化结果。 创建并绘制一个有向图。 s [1 2 3 3 3 3 4 5 6 7 8 9 9 9 10]; t [7 6 1 5 6 8 2 4 4 3 7 1 6 8 2]; G dig…...

CSerialPort教程4.3.x (2) - CSerialPort源码简介

CSerialPort教程4.3.x (2) - CSerialPort源码简介 前言 CSerialPort项目是一个基于C/C的轻量级开源跨平台串口类库&#xff0c;可以轻松实现跨平台多操作系统的串口读写&#xff0c;同时还支持C#, Java, Python, Node.js等。 CSerialPort项目的开源协议自 V3.0.0.171216 版本…...

【数据结构OJ题】有效的括号

原题链接&#xff1a;https://leetcode.cn/problems/valid-parentheses/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 这道题目主要考查了栈的特性&#xff1a; 题目的意思主要是要做到3点匹配&#xff1a;类型、顺序、数量。 题目给的例子是比较…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...