作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

gtest 简介

GoogleTest(也称为gtest)是由 Google 开发的一个 C++ 单元测试框架,用于编写、组织和运行自动化测试代码。它支持断言(如 EXPECT_EQ、ASSERT_TRUE 等)、测试夹具(test fixtures)、参数化测试等高级功能,能够帮助开发者在开发过程中快速发现和定位问题。GoogleTest 具有良好的跨平台性,广泛用于 C++ 项目的测试验证,是工业界最常用的 C++ 测试框架之一

构建

gtest 源代码下载:github 下载
百度网盘下载:下载链接
提取码: kjef

百度网盘里除了源代码,还有编译好的动态库可以直接使用,编译环境是 vs2019 64位
在这里插入图片描述
在 qt 中使用 gtest 需要导入依赖库,把 googletest_msvc2019 文件夹放在 pro 文件同目录下,然后在 pro 文件中添加以下信息:

INCLUDEPATH += $$PWD/googletest_msvc2019/includewin32:CONFIG(release, debug|release): {LIBS += -L$$PWD/googletest_msvc2019/lib/Release/ -lgmockLIBS += -L$$PWD/googletest_msvc2019/lib/Release/ -lgmock_mainLIBS += -L$$PWD/googletest_msvc2019/lib/Release/ -lgtestLIBS += -L$$PWD/googletest_msvc2019/lib/Release/ -lgtest_main
}
else:win32:CONFIG(debug, debug|release): {LIBS += -L$$PWD/googletest_msvc2019/lib/Debug/ -lgmockLIBS += -L$$PWD/googletest_msvc2019/lib/Debug/ -lgmock_mainLIBS += -L$$PWD/googletest_msvc2019/lib/Debug/ -lgtestLIBS += -L$$PWD/googletest_msvc2019/lib/Debug/ -lgtest_main
}

gtest 语法

1. TEST

这是定义测试用例的基本宏。它接受两个参数:测试用例的名称和一个测试函数

TEST(TestSuiteName, TestName) {  // 测试代码  
}

2. TEST_F

用于定义继承自某个测试夹具(Test Fixture)的测试。测试夹具是一个类,用于设置测试前的环境和清理测试后的环境。TEST_F 宏接受两个参数:测试夹具的类名和测试名称

class MyFixture : public ::testing::Test {  
protected:  // 设置测试环境  void SetUp() override {  // 初始化代码  }  // 清理测试环境  void TearDown() override {  // 清理代码  }  
};  TEST_F(MyFixture, TestName) {  // 测试代码  
}

3. TEST_P

用于定义参数化测试。参数化测试允许你运行同一个测试代码,但是使用不同的参数集。首先,你需要定义一个测试夹具类并继承自 ::testing::TestWithParam,其中T是参数的类型。然后,使用 TEST_P 宏定义测试

class MyParameterizedTest : public ::testing::TestWithParam<int> {  
protected:  void SetUp() override {  // 使用GetParam()获取参数  }  
};  TEST_P(MyParameterizedTest, TestName) {  // 测试代码,使用GetParam()获取参数  
}  INSTANTIATE_TEST_SUITE_P(instanceName, MyParameterizedTest, ::testing::Values(1, 2, 3, 4));

4. SCOPED_TRACE

用于在测试失败时添加额外的日志信息的宏。它在日志消息中添加一个额外的文本信息,这对于理解测试失败时的上下文非常有用。通常与 EXPECT_ 或 ASSERT_ 宏一起使用,以便在测试失败时提供更多的调试信息

SCOPED_TRACE("SubFunction called with value " << value);

5. EXPECT_ 和 ASSERT_ 系列宏

这些宏用于在测试中验证代码的行为。EXPECT_ 系列的宏在遇到失败时会记录错误并继续执行测试中的后续语句,而 ASSERT_ 系列的宏在遇到失败时会记录错误并终止当前测试。下面以非致命断言 EXPECT_ 系列为例:

非致命断言结果
EXPECT_TRUE(condition)检查 condition 是否为真
EXPECT_FALSE(condition)检查 condition 是否为假
--
EXPECT_EQ(val1, val2)val1 == val2
EXPECT_NE(val1, val2)val1 != val2
EXPECT_LT(val1, val2)val1 < val2
EXPECT_LE(val1, val2)val1 <= val2
EXPECT_GT(val1, val2)val1 > val2
EXPECT_GE(val1, val2)val1 >= val2
--
EXPECT_STREQ(str1, str2)用于比较两个C字符串是否相等
EXPECT_STRNE(str1, str2)用于比较两个C字符串是否不相等
EXPECT_STRCASEEQ(str1, str2)用于比较两个C字符串是否相等,‌忽略字母大小写差异
EXPECT_STRCASENE(str1, str2)用于比较两个C字符串是否不相等,‌忽略字母大小写差异
--
EXPECT_FLOAT_EQ(val1, val2)检测浮点数 val1 和 val2 是否相等,允许一定的误差
EXPECT_DOUBLE_EQ(val1, val2)检测双精度浮点数 val1 和 val2 是否相等,允许一定的误差
EXPECT_NEAR(val1, val2, abs_error)检查浮点数 val1 和 val2 的差值的绝对值是否小于或等于 abs_error
--
EXPECT_THROW(statement, expected_exception)检测 statement 是否抛出指定类型的异常 expected_exception
EXPECT_ANY_THROW(statement)检测 statement 是否抛出任何异常
ASSERT_NO_THROW(statement)检测 statement 是否不抛出异常
--
EXPECT_DEATH(statement, regex)用于测试在执行 statement 时是否会导致程序崩溃,并且崩溃信息是否符合正则表达式 regex 的要求
EXPECT_THAT(actual, matcher)用于进行复杂的条件检查,特别是在使用匹配器时。matcher 用于检查 actual 的匹配器

6. SUCCEED 和 FAIL

SUCCEED() 会标记当前测试用例成功并立即结束测试。无论之前的测试代码是否存在错误,都会标记为成功,并且SUCCEED 后面的代码不会被执行
FAIL() 会标记当前测试用例为失败并立即结束测试。可以用来在测试代码中发现不可接受的状态时报告测试失败。在 FAIL() 之后的代码不会被执行。可以 FAIL() << “ ”;用于在测试失败后输出一段信息

7. ADD_FAILURE 和 ADD_FAILURE_AT

ADD_FAILURE 用于手动添加测试失败的报告,而不依赖于某个特定断言的失败。可以在代码中的任何一个位置来标记,当执行到 ADD_FAILUR 时,gtest 会报告测试失败,但程序仍然会继续执行后续的代码
ADD_FAILURE_AT 允许在指定的文件名和行号处报告失败

Qt 中的应用示例

// 源代码功能:加载一个json文件存储在内存中
QJsonObject CommonFunction::getObjFromConfig(QString fileName)
{QFileInfo fileInfo(fileName);if ( !fileInfo.isFile() ) {return QJsonObject();}QFile file(fileName);if ( !file.open(QIODevice::ReadOnly) ) {return QJsonObject();}// get json objectQByteArray jsonData = file.readAll();// QString jsonString = QString::fromUtf8(jsonData);// qDebug() << jsonString;file.close();QJsonDocument jsonDoc(QJsonDocument::fromJson(jsonData));QJsonObject obj = jsonDoc.object();return obj;
}

创建一个头文件 test_getObjFromConfig.h 编写单元测试代码

#ifndef TEST_GETOBJFROMCONFIG_H
#define TEST_GETOBJFROMCONFIG_H#include <gtest/gtest.h>
#include "commonfunction.h"
#include <QTemporaryFile>class Test_GetObjFromConfig : public testing::Test
{
protected:CommonFunction* commonFun;void SetUp() override {commonFun = new CommonFunction();}void TearDown() override {delete commonFun;}
};// 测试文件不存在的情况
TEST_F(Test_GetObjFromConfig, FileNotFoundReturnsEmptyObject) {QString nonExistentFile = "non_existent_file.json";QJsonObject result = commonFun->getObjFromConfig(nonExistentFile);EXPECT_TRUE(result.isEmpty());
}// 测试文件无法打开的情况(例如:没有权限)
TEST_F(Test_GetObjFromConfig, UnreadableFileReturnsEmptyObject) {// 创建一个临时文件并立即关闭它QTemporaryFile tempFile("XXXXXX.json");tempFile.open();tempFile.close();// 设置文件权限为只读(假设当前用户无法写入)QFile file(tempFile.fileName());file.setPermissions(QFile::ReadOwner);QJsonObject result = commonFun->getObjFromConfig(tempFile.fileName());EXPECT_TRUE(result.isEmpty());
}// 测试有效的JSON文件
TEST_F(Test_GetObjFromConfig, ValidJsonFileReturnsParsedObject) {// 创建临时文件并写入有效的JSON内容QTemporaryFile tempFile("XXXXXX.json");if (tempFile.open()) {QString jsonContent = R"({"company":"swyl"})";tempFile.write(jsonContent.toUtf8());tempFile.close();QJsonObject result = commonFun->getObjFromConfig(tempFile.fileName());EXPECT_FALSE(result.isEmpty());EXPECT_EQ(result["company"].toString(), "swyl");} else {FAIL() << "无法创建临时文件";}
}// 测试无效的JSON文件
TEST_F(Test_GetObjFromConfig, InvalidJsonFileReturnsEmptyObject) {// 创建临时文件并写入无效的JSON内容QTemporaryFile tempFile("XXXXXX.json");if (tempFile.open()) {QString invalidJson = "invalid json content";tempFile.write(invalidJson.toUtf8());tempFile.close();QJsonObject result = commonFun->getObjFromConfig(tempFile.fileName());EXPECT_TRUE(result.isEmpty());} else {FAIL() << "无法创建临时文件";}
}// 测试空JSON文件
TEST_F(Test_GetObjFromConfig, EmptyFileReturnsEmptyObject) {// 创建空的临时文件QTemporaryFile tempFile("XXXXXX.json");if (tempFile.open()) {tempFile.close();QJsonObject result = commonFun->getObjFromConfig(tempFile.fileName());EXPECT_TRUE(result.isEmpty());} else {FAIL() << "无法创建临时文件";}
}#endif // TEST_GETOBJFROMCONFIG_H

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF TreeView 数据绑定完全指南:MVVM 模式实现

WPF TreeView 数据绑定完全指南&#xff1a;MVVM 模式实现 一、TreeView 绑定的核心概念1.1 MVVM 模式下的 TreeView 绑定原理1.2 绑定关系示意图 二、完整实现步骤2.1 创建节点模型类2.2 创建 ViewModel2.3 XAML 绑定配置2.4 设置 Window 的 DataContext 三、关键特性详解3.1 …

坤驰科技QTS4200战鹰(Battle Eagle)系列实时频谱分析记录回放系统

QTS4200战鹰(Battle Eagle)系列 实时频谱分析记录回放系统 精准采集&#xff5c;高效回放&#xff5c;拓展频谱分析新边界 坤驰科技倾力打造新一代集实时频谱分析、高速信号记录与精准信号回放于一体的便携式系统&#xff0c;为无线电监测、无线通信、国防等领域提供全面而高…

Flask(二) 路由routes

文章目录 基本路由定义路由参数路由规则设置请求方法&#xff08;GET/POST&#xff09;路由函数返回静态文件和模板Blueprint&#xff08;模块化路由&#xff09;显示当前所有路由 Flask 路由是 Web 应用程序中将 URL 映射到 Python 函数的机制。 定义路由&#xff1a;使用 app…

在el-image组件的预览中添加打印功能(自定义功能)

思路&#xff1a;给图片添加点击事件&#xff0c;通过js获取预览的工具栏&#xff0c;在工具栏中添加自定义按钮及事件 1、html 中 image标签 <el-image style"width: 139px; height: 89px" :src"fileUrl" :preview-src-list"[fileUrl]" cli…

TongWeb替换tomcat

1、背景 国家近年来大力推进信息技术应用创新产业&#xff08;信创&#xff09;&#xff0c;要求关键领域采用自主可控的国产软硬件。Tomcat作为国外开源产品&#xff0c;存在潜在的安全风险和技术依赖。TongWeb作为国产中间件&#xff0c;符合信创目录要求&#xff0c;满足政府…

联合语音和文本机器翻译,支持多达100种语言(nature子刊论文研读)

简介&#xff1a; &#x1f30d; SEAMLESSM4T 是一种单一模型&#xff0c;实现了跨越多达 101 种源语言和多种目标语言的语音到语音、语音到文本、文本到语音和文本到文本翻译及自动语音识别。&#x1f680; 该模型性能显著超越现有级联系统&#xff0c;特别是在语音到文本和语…

网站公安网安备案查询API集成指南

网站公安网安备案查询API集成指南 引言 随着互联网应用的日益普及&#xff0c;网络安全和个人隐私保护越来越受到重视。公安网安备案作为保障网络安全的重要措施之一&#xff0c;对于确保网站合法合规运营具有重要意义。为了帮助开发者更加便捷地获取网站的公安网安备案信息&a…

如何用远程调试工具排查 WebView 与原生通信问题(iOS或Android)

WebView 在移动端开发中的角色越来越关键&#xff0c;尤其在混合架构&#xff08;Hybrid&#xff09;项目中&#xff0c;它作为前端与原生的桥梁&#xff0c;承载了大量交互行为。但这个桥梁并不总是稳固&#xff0c;尤其是在涉及 JSBridge 通信 时&#xff0c;前端调用原生接口…

使用 spark-submit 运行依赖第三方库的 Python 文件

python文件在spark集群运行真的麻烦&#xff0c;烦冗 spark运行分为了三个模式&#xff0c;本地模式/client模式/cluster模式 文章目录 本地模式client模式cluster模式参考 本地模式 现在的spark支持python3了&#xff0c;支持python2的版本已经很落后了&#xff0c;所以需要…

【android bluetooth 协议分析 05】【蓝牙连接详解2】【acl_interface_t介绍】

1. acl_interface_t 介绍 acl_interface_t 结构体及其子结构体&#xff0c;目的是封装处理 Classic、LE、SCO 连接及链路事件的回调函数&#xff0c;用于 HCI 事件与上层蓝牙协议栈的解耦分发。 system/main/shim/acl_legacy_interface.h typedef struct {void (*on_connect…

TouchDIVER Pro触觉手套:虚拟现实中的多模态交互新选择

随着虚拟现实技术的发展&#xff0c;用户对沉浸式体验的需求不断提升。TouchDIVER Pro触觉手套通过力反馈、纹理渲染和温度提示三种核心机制&#xff0c;为用户提供更真实的触觉感知体验。六个驱动点分布于五指与手掌&#xff0c;结合全手追踪与低延迟连接&#xff0c;实现精准…

想考华为HCIA-AI,应该怎么入门?

华为HCIA-AI Solution认证作为华为人工智能认证体系的起点&#xff0c;吸引了许多希望进入AI领域或提升专业技能的学习者。如果你正考虑考取这个认证&#xff0c;这份纯科普向的入门指南希望能够帮你理清学习路径和关键准备点&#xff01; 第一、明确认证目标与要求 HCIA-AI S…

【Oracle篇】Windows平台单进程多线程架构设计与实现(比对Linux多进程架构)

&#x1f4ab;《博主主页》&#xff1a; &#x1f50e; CSDN主页__奈斯DB &#x1f50e; IF Club社区主页__奈斯、 &#x1f525;《擅长领域》&#xff1a;擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、N…

在微服务中使用 Sentinel

在微服务中集成 Sentinel 1. 添加依赖 对于 Spring Cloud 项目&#xff0c;首先需要添加 Sentinel 的依赖&#xff1a; <!-- Spring Cloud Alibaba Sentinel --> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-…

中断控制与实现

一、中断基本概念 1、中断 中断是一种异步事件&#xff0c;用于通知处理器某个事件已经发生&#xff0c;需要处理器立即处理。由于I/O操作的不确定因素以及处理器和I/O设备之间的速度不匹配&#xff0c;I/O设备可以通过某种硬件信号异步唤醒对应的处理器的响应&#xff0c;这些…

前端跨域解决方案(7):Node中间件

1 Node 中间件核心 1.1 为什么开发环境需要 Node 代理&#xff1f; 在前端开发中&#xff0c;我们常遇到&#xff1a;前端运行在localhost:3000&#xff0c;后端 API 在localhost:4000&#xff0c;跨域导致请求失败。而传统解决方案有以下局限性&#xff1a; 修改后端 CORS 配…

iwebsec靶场-文件上传漏洞

01-前端JS过滤绕过 1&#xff0c;查看前端代码对文件上传的限制策略 function checkFile() { var file document.getElementsByName(upfile)[0].value; if (file null || file "") { alert("你还没有选择任何文件&a…

GitHub 趋势日报 (2025年06月23日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 390 suna 387 system-prompts-and-models-of-ai-tools 383 Web-Dev-For-Beginners…

告别水印烦恼,一键解锁高清无痕图片与视频!

在这个数字化飞速发展的时代&#xff0c;无论是设计小白还是创意达人&#xff0c;都可能遇到这样的困扰&#xff1a;心仪的图片或视频因水印而大打折扣&#xff0c;创意灵感因水印而受限。别急&#xff0c;今天就为大家带来几款神器&#xff0c;让你轻松告别水印烦恼&#xff0…

LangChain4j在Java企业应用中的实战指南:构建RAG系统与智能应用-2

LangChain4j在Java企业应用中的实战指南&#xff1a;构建RAG系统与智能应用-2 开篇&#xff1a;LangChain4j框架及其在Java生态中的定位 随着人工智能技术的快速发展&#xff0c;尤其是大语言模型&#xff08;Large Language Models, LLMs&#xff09;的广泛应用&#xff0c;…