软件测试:C++ Google Test单元测试框架GTest
目录
- 编译和安装
- 框架使用
- Assertions
- Google Testing
- Google Mocking
- Matchers
- Actions
- 运行结果
最近在写项目的时候,学到了许多关于软件测试的知识,也不断的使用新的测试框架和测试工具,每次总是机械式的拼接其他人的代码,代码发生错误也不知道怎么解决,因此我打算直接将其学一遍,以便为了更灵活的写测试代码
编译和安装
下载地址:Google Test Github网站
然后直接在CMakeLists.txt引入就好了
include_directories(include) # 设置include路径set(CXXFLAGS -std=c++11 -lgtest -lpthread)
add_compile_options(${CXXFLAGS})target_link_libraries(test gtest pthread) # 链接gtest静态库
框架使用
框架的使用主要分为几个模块:Assertions、Google Testing、Google Mocking、Matchers、Actions
Assertions
这一部分主要是一些断言和比较宏定义,内容较多,以下是一部分,想看全部的可以去看源码
这一部分理解比较简单,不做概述
#define EXPECT_THROW(statement, expected_exception) \GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
#define EXPECT_NO_THROW(statement) \GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
#define EXPECT_ANY_THROW(statement) \GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
#define ASSERT_THROW(statement, expected_exception) \GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
#define ASSERT_NO_THROW(statement) \GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
#define ASSERT_ANY_THROW(statement) \GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
Google Testing
这部分是框架的主要部分,也是开发人员接触最多的地方
首先来介绍三个常用的宏:TEST、TEST_F、TEST_P
TEST:一般测试,在其内部设置断言
TestSuiteName定义了测试套件名称,TestName定义了自定义测试名
- 注意这两个的命名不要包括下划线
_
TEST(TestSuiteName, TestName)
{// statements
}
TEST_F:多样测试,就是多种不同情况的测试中都会使用相同一份的测试数据的情况
TEST_P(TestFixtureName, TestName)
{// statements
}
TEST_P:值参数化测试,自动化产生输入参数进行测试
TEST_P(TestFixtureName, TestName)
{// statements
}
以TEST_P为例写一个小demo
首先定义一个测试套件类,在其中定义要产生测试输入参数的类型
// 其中TestWithParam从Test类和WithParamInterface类派生来的,这两个类是必要的
class FooTest : public ::testing::TestWithParam<int> {};
产生自动化输入参数结构
INSTANTIATE_TEST_CASE_P(InstantiationName, // 此处自定义名称FooTest, // 测试套件类::testing::Values(1, 2, 3));
第三个参数是可更改的,比如Range、Bool、ValuesIn、Values
INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,testing::Values(...),[](const testing::TestParamInfo<MyTestSuite::ParamType>& info) {// Can use info.param here to generate the test suffixstd::string name = ...return name;});
要注意的是Combine,它会把其中的变量组成一个联合排列输入参数(确保支持tr/tuple<T>特性)
class Bis {bool Even(int dd) {}bool Suc(bool dc) {}
};class CombineTest : public ::testing::TestWithParam< ::testing::tuple<bool, int> > {
protected:bool CheckData() {bool dc = ::testing::get<0>(GetParam());int dd = ::testing::get<1>(GetParam());return bis.Suc(dc) && bis.Even(dd);}
private:Bis bis;
}TEST_P(MyCombineTest, CombineTestUnit)
{EXPECT_TRUE(CheckData());
}INSTANTIATE_TEST_CASE_P(TestBisValuesCombine, CombineTest, ::testing::Combine(::testing::Bool(), ::testing::Values(3, 4)));
最后在TEST_P中写测试代码
bool IsPrime(int n)
{return n > 0;
}TEST_P(FooTest, DoesBlah)
{// Inside a test, access the test parameter with the GetParam() method// of the TestWithParam<T> class://在测试中,使用TestWithParam <T>类的GetParam()方法访问测试参数:int n = GetParam();EXPECT_TRUE(IsPrime(n));// ...
}
其他部分API用的时候直接看官网就好了,主体是这三个API,其他基本上都是辅助宏
Google Mocking
有点类似于伪装接口,一般情况下用不着,不做概述
Matchers
有点类似于前面的断言,直接看部分源码(在gmok-matchers.h文件中)
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrEq(const std::wstring& str) {return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::wstring>(str, true, true));
}// Matches a string not equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrNe(const std::wstring& str) {return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::wstring>(str, false, true));
}// Matches a string equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseEq(const std::wstring& str) {return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::wstring>(str, true, false));
}
Actions
这玩意也是一个和断言差不多的东西,看部分源码
template <size_t k, typename Ptr>
struct SaveArgAction {Ptr pointer;template <typename... Args>void operator()(const Args&... args) const {*pointer = std::get<k>(std::tie(args...));}
};template <size_t k, typename Ptr>
struct SaveArgPointeeAction {Ptr pointer;template <typename... Args>void operator()(const Args&... args) const {*pointer = *std::get<k>(std::tie(args...));}
};
运行结果
下面来看看一个普通测试套件的运行结果
#include <gtest/gtest.h>
#include <stdint.h>
#include <stdio.h>int Add(uint32_t a, uint32_t b)
{return a + b;
}TEST(LLT, MAIN)
{EXPECT_EQ(Add(1U, 1U), 1U);
}int main(int argc, char **argv)
{testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
ubuntu@VM-8-16-ubuntu:~/finale/llt/build$ ./test
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from LLT
[ RUN ] LLT.MAIN
/home/ubuntu/finale/llt/src/test_main.cc:17: Failure
Expected equality of these values:add(1U, 1U)Which is: 21UWhich is: 1
[ FAILED ] LLT.MAIN (0 ms)
[----------] 1 test from LLT (0 ms total)[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] LLT.MAIN1 FAILED TEST
这个框架自定义的界面还是很好看的!
相关文章:
软件测试:C++ Google Test单元测试框架GTest
目录 编译和安装框架使用AssertionsGoogle TestingGoogle MockingMatchersActions 运行结果 最近在写项目的时候,学到了许多关于软件测试的知识,也不断的使用新的测试框架和测试工具,每次总是机械式的拼接其他人的代码,代码发生错…...
大数据面试题 —— HBase
目录 什么是HBase简述HBase 的数据模型HBase 的读写流程HBase 在写的过程中的region的split的时机HBase 和 HDFS 各自的使用场景HBase 的存储结构HBase 中的热现象(数据倾斜)是怎么产生的,以及解决办法有哪些HBase rowkey的设计原则HBase 的列…...
SCI一区 | Matlab实现GWO-TCN-BiGRU-Attention灰狼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测
SCI一区 | Matlab实现GWO-TCN-BiGRU-Attention灰狼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现GWO-TCN-BiGRU-Attention灰狼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述程序…...
SpringMVC的执行原理
SpringMVC的执行原理可以简单地概括为以下几个步骤: 客户端发送请求:客户端(一般是浏览器)发送HTTP请求到服务器,请求特定的URL资源。 前端控制器(DispatcherServlet)接收请求:在Sp…...
Qt + HTTP 线程交互类封装
介绍 QT的HTTP模块封装的交互类,线程运行。使用时添加自己的业务逻辑即可 代码 头文件 /*** file httpcontroller.h* brief 云台相机的协议交互类* author xintong-zhou* date 2024-03-13*/#ifndef HTTPCONTROLLER_H #define HTTPCONTROLLER_H#include <QNet…...
GitHub Copilot+ESP开发实战-串口
上篇文章讲了GitHub Copilot在应用中可能遇到的问题,接下来小启就简单介绍下GitHub Copilot在ESP32开发中C语言实现串口功能,感兴趣的可以看看。 一、向Copilot提问: 1. ESP32用C语言实现串口初始化; 2.配置uart为1,…...
C# 使用ffmpeg将图片保存为mp4视频
使用 FFmpeg 这个强大的多媒体处理工具,可以轻松地将一系列图片转换为一个 MP4 视频文件。以下是一个基本的命令行示例来完成这个任务: ffmpeg -framerate 25 -i image-%03d.jpg -c:v libx264 -r 30 -pix_fmt yuv420p output.mp4 命令参数说明…...
Java安全技术及代码审计技巧
概述 Java安全编码和代码审计是确保Java应用程序安全性的重要环节。本文旨在介绍Java中常见的Web漏洞、安全编码示例以及一些常见漏洞函数,并提供一个自动化查找危险函数的Python脚本。 1. XML外部实体 (XXE) 漏洞 介绍 XML文档结构包括XML声明、DTD文档类型定义&…...
C# 使用OpenCvSharp4将Bitmap合成为MP4视频的环境
环境安装步骤: 在VS中选中项目或者解决方案,鼠标右键,选择“管理Nuget包”,在浏览窗口中搜索OpenCVSharp4 1.搜索OpenCvSharp4,选择4.8.0版本,点击安装 2.搜索OpenCvSharp4.runtime.win,选择4.8.0版本,点…...
[游戏开发][Unity] 导出Xcode工程,完成调试与发布
Unity导出Xcode工程(模拟器版本与真机调试) [游戏开发][Unity] 打包Xcode工程模拟器真机调试_unity5 打包xcod-CSDN博客 Unity导出发布版本Xcode工程,上传app到官网,正式发布或创建TestFlight Xcode发布AppStore与TestFlight全流程_xcode 上传到testfit-…...
JSONP 实现跨域请求案例
后端使用 express 搭建,案例代码如下: const express require(express)const app express() const PORT 3000app.get(/data, (req, res) > {const jsonData {name: Alan,age: 666,city: GD}const callback req.query.callback // 获取前端中的回…...
2024年智慧城市、人文发展与区域经济国际会议(ICSCCDRE 2024)
2024年智慧城市、人文发展与区域经济国际会议(ICSCCDRE 2024) 2024 International Conference on Smart Cities, Cultural Development and Regional Economy 会议简介: 城市经济人文发展是一个综合性的过程,它关注城市在经济、…...
目标检测——PP-YOLO算法解读
PP-YOLO系列,均是基于百度自研PaddlePaddle深度学习框架发布的算法,2020年基于YOLOv3改进发布PP-YOLO,2021年发布PP-YOLOv2和移动端检测算法PP-PicoDet,2022年发布PP-YOLOE和PP-YOLOE-R。由于均是一个系列,所以放一起解…...
多特征变量序列预测(11) 基于Pytorch的TCN-GRU预测模型
往期精彩内容: 时序预测:LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 风速预测(一)数据集介绍和预处理-CSDN博客 风速预测(二)基于Pytorch的EMD-LSTM模型-CSDN博客 风速预测ÿ…...
Lvs+keepalived+nginx搭建高可用负载均衡集群
环境配置 master主机192.168.199.149,虚拟IP192.168.199.148 back备机192.168.199.150 真实服务器1 192.168.199.155 真实服务器2 192.168.199.156 关闭防火墙和selinux master配置(149) 添加虚拟IP ip addr add 192.168.199.148/24 …...
WPF —— 控件模版和数据模版
1:控件模版简介: 自定义控件模版:自己添加的样式、标签,控件模版也是属于资源的一种, 每一个控件模版都有一唯一的 key,在控件上通过template属性进行绑定 什么场景下使用自定义控件模版,当项目里面多个地方…...
如何动态修改spring中定时任务的调度策略(1)
在我们日常开发中经常会调度工具来处理一下需要定时执行的任务,比如定时导出报表数据给业务方发送邮件。你在工作中是如何这种定时调度? 如何实现调度任务 使用java技术栈的老铁来说,现成定时调度的解决方案应该有很多,总结来说…...
idea import的maven类报红
idea 报红/显示红色的原因 一般报红,显示红色,是因为 idea 在此路径下,找不到这个类。 找到是哪个 jar 包的类导致 idea 报红 点击报红的路径的上一层,进入jar 包。比如: import com.aaa.bbb.ccc.DddDto;这个 impo…...
React——class组件中setState修改state
class组件中通过state去存储当前组件的数据,那怎么对其进行修改呢?就是方法this.setState({ 要修改的部分数据 }) setState() 作用:1 、修改 state 内容;2 、更新 UI 特别注意:react的核心其实是虚拟dom(数…...
搭建基于 Snowflake 的 CI/CD 最佳实践!
Snowflake 提供了可扩展的计算和存储资源,和基于 SQL 的界面 Snowsight,方便用户进行数据操作和分析。然而,如果用户想将自己的 CI/CD 流程与 Snowflake 集成时,会发现一些不便之处(尤其相比其 SnowSight 优秀的查询能…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
