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

【C++】Google Test(gtest)单元测试

文章目录

  • Google Test(gtest)单元测试
    • 使用示例
    • 更多用法
      • 测试夹具

Google Test(gtest)单元测试

单元测试是一种软件测试方法,它旨在将应用程序的各个部分(通常是方法或函数)分离出来并独立测试,以确保每个部分都能够按预期工作。

gtest是Google公司发布的一款开源的C/C++单元测试框架。gtest的TEST 宏用于定义单个测试用例,其基本语法为:

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

其中 TestCaseName为测试用例的名称,用于将相关的测试分组在一起,以便在测试结果中更容易地识别和归类。TestName为具体测试的名称,一般描述测试的目的。

每个测试用例包含一个或多个检查点,这些检查点使用断言来验证代码的行为。包括以EXPECT_ 为前缀的非致命断言,其在测试失败时程序会继续执行;和以 ASSERT_ 味前缀的致命断言,其在测试失败时程序立即终止。基本的非致命断言包括:

  • 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

对应的致命断言:

  • ASSERT_EQ(val1, val2)
  • ASSERT_NE(val1, val2)
  • ASSERT_LT(val1, val2)
  • ASSERT_LE(val1, val2)
  • ASSERT_GT(val1, val2)
  • ASSERT_GE(val1, val2)

除此之外,还有专门用于字符串比较的断言:

  • EXPECT_STREQ(str1, str2):检查 str1str2 是相同的字符串。
  • EXPECT_STRNE(str1, str2):检查 str1str2 是不同的字符串。
  • EXPECT_STRCASEEQ(str1, str2):检查 str1str2 是相同的字符串,忽略大小写。
  • EXPECT_STRCASENE(str1, str2):检查 str1str2 是不同的字符串,忽略大小写。

用于浮点数比较的断言:

  • EXPECT_FLOAT_EQ(val1, val2):检查 val1val2 具有相同的浮点值。
  • EXPECT_DOUBLE_EQ(val1, val2):检查 val1val2 具有相同的双精度值。
  • EXPECT_NEAR(val1, val2, abs_error):检查 val1val2 之间的差值在 abs_error 范围内。

用于布尔值的断言:

  • EXPECT_TRUE(condition):检查 condition 为真。
  • EXPECT_FALSE(condition):检查 condition 为假。

使用示例

项目结构:

gtest_demo/
├── CMakeLists.txt
├── include/
│   └── math_functions.h
├── src/
│   └── math_functions.cpp
└── tests/└── test_math_functions.cpp

CMakeLists.txt

# 指定CMake的最低版本
cmake_minimum_required(VERSION 3.10)# 定义项目名称
project(gtest_demo)# 设置C++标准为C++11,并且为强制要求
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)# 添加当前项目的include目录,以便编译器能找到头文件
include_directories(${PROJECT_SOURCE_DIR}/include)# 添加源文件,生成一个名为math_functions的静态库
add_library(math_functions src/math_functions.cpp)# 查找Google Test库,确保系统已安装GTest
find_package(GTest REQUIRED)
# 添加GTest的include目录
include_directories(${GTEST_INCLUDE_DIRS})# 添加测试源文件,生成一个名为runTests的可执行文件
add_executable(runTests tests/test_math_functions.cpp)# 链接math_functions, gtest库和pthread库到可执行文件runTests
# gtest框架在实现上使用了多线程(pthread)来管理测试并发执行
target_link_libraries(runTests ${GTEST_LIBRARIES} pthread math_functions)# 启用测试功能
enable_testing()
# 添加一个名为runTests的测试
add_test(NAME runTests COMMAND runTests)

include/math_functions.h

#ifndef MATH_FUNCTIONS_H // 头文件保护
#define MATH_FUNCTIONS_Hint add(int a, int b);
int subtract(int a, int b);
float add(float a, float b);
double add(double a, double b);#endif 

src/math_functions.cpp :

#include "math_functions.h"int add(int a, int b) {return a + b + 1; // 故意错误
}int subtract(int a, int b) {return a - b;
}float add(float a, float b) {return a + b;
}double add(double a, double b) {return a + b;
}

tests/test_math_functions.cpp:

#include <gtest/gtest.h>
#include "math_functions.h"// 测试add函数(整数)
TEST(MathFunctionsTest, AddInt) {EXPECT_EQ(add(1, 1), 2);EXPECT_EQ(add(-1, -1), -2);EXPECT_EQ(add(0, 0),2); 
}// 测试subtract函数
TEST(MathFunctionsTest, Subtract) {EXPECT_EQ(subtract(2, 1), 1);EXPECT_EQ(subtract(-1, -1), 0);EXPECT_EQ(subtract(0, 0), 0); 
}// 测试add函数(浮点数)
TEST(MathFunctionsTest, AddFloat) {EXPECT_FLOAT_EQ(add(0.1f, 0.2f), 0.3f);EXPECT_NEAR(add(0.1f, 0.2f), 0.3f, 1e-6);
}TEST(MathFunctionsTest, AddDouble) {EXPECT_DOUBLE_EQ(add(0.1, 0.2), 0.3);EXPECT_NEAR(add(0.1, 0.2), 0.3, 1e-6);
}int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);// 初始化 Google Test return RUN_ALL_TESTS();  // 运行所有测试用例
}

编译和运行测试

    mkdir buildcd buildcmake..make./runTest
[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from MathFunctionsTest
[ RUN      ] MathFunctionsTest.AddInt
/home/hrn/CppProjects/gtest_demo/tests/test_math_functions.cpp:6: FailureExpected: add(1, 1)Which is: 3
To be equal to: 2
/home/hrn/CppProjects/gtest_demo/tests/test_math_functions.cpp:7: FailureExpected: add(-1, -1)Which is: -1
To be equal to: -2
/home/hrn/CppProjects/gtest_demo/tests/test_math_functions.cpp:8: FailureExpected: add(0, 0)Which is: 1
To be equal to: 0
[  FAILED  ] MathFunctionsTest.AddInt (0 ms)
[ RUN      ] MathFunctionsTest.Subtract
[       OK ] MathFunctionsTest.Subtract (0 ms)
[ RUN      ] MathFunctionsTest.AddFloat
[       OK ] MathFunctionsTest.AddFloat (0 ms)
[ RUN      ] MathFunctionsTest.AddDouble
[       OK ] MathFunctionsTest.AddDouble (0 ms)
[----------] 4 tests from MathFunctionsTest (0 ms total)[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 3 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] MathFunctionsTest.AddInt1 FAILED TEST

3个测试通过,1个不通过,add函数有误.

更多用法

测试夹具

测试夹具(Test Fixture)用于提供一个环境,允许开发者在多个测试用例之间共享设置和清理的代码,确保每个测试用例都在相同或可控的初始状态下运行。

在gtest中,测试夹具通常是通过派生自::testing::Test类的子类来实现的,并通过TEST_F()宏定义测试用例。

示例:

#include <gtest/gtest.h>
#include <vector>// 假设有一个简单的类 MyClass
class MyClass {
public:MyClass(int data) : basevalue(data) {}void add(int data) { basevalue += data; }int getdata() const { return basevalue; }private:int basevalue;
};// 测试夹具类
class MyTest : public ::testing::Test {
protected:MyClass *my;std::vector<int> sharedVector;// 在每个测试用例执行前设置环境void SetUp() override {my = new MyClass(100);sharedVector = {1, 2, 3, 4, 5};}// 在每个测试用例执行后清理环境void TearDown() override {delete my;}
};// 使用 TEST_F() 宏编写测试用例
TEST_F(MyTest, test1) {my->add(10);EXPECT_EQ(my->getdata(), 110);sharedVector.push_back(6);EXPECT_EQ(sharedVector.size(), 6);EXPECT_EQ(sharedVector.back(), 6);
}TEST_F(MyTest, test2) {my->add(100);EXPECT_EQ(my->getdata(), 200);sharedVector.pop_back();EXPECT_EQ(sharedVector.size(), 4);EXPECT_EQ(sharedVector.back(), 4);
}TEST_F(MyTest, test3) {my->add(-50);EXPECT_EQ(my->getdata(), 50);sharedVector[0] = 10;EXPECT_EQ(sharedVector[0], 10);EXPECT_EQ(sharedVector.size(), 5);
}TEST_F(MyTest, test4) {my->add(0);EXPECT_EQ(my->getdata(), 100);sharedVector.clear();EXPECT_TRUE(sharedVector.empty());
}

在这个示例中,测试夹具类 MyTest 通过继承 ::testing::Test 类,实现了 SetUp()TearDown() 方法。在 SetUp() 方法中,初始化了一个 MyClass 对象和一个 std::vector<int>。在 TearDown() 方法中,清理了 MyClass 对象。

每个测试用例 (test1test2test3test4) 都使用了相同的测试夹具 MyTest,共享了初始化和清理代码。在每个测试用例中,MyClass 对象和 sharedVector 都被重新初始化,以确保测试用例之间相互独立。

相关文章:

【C++】Google Test(gtest)单元测试

文章目录 Google Test&#xff08;gtest&#xff09;单元测试使用示例更多用法测试夹具 Google Test&#xff08;gtest&#xff09;单元测试 单元测试是一种软件测试方法&#xff0c;它旨在将应用程序的各个部分&#xff08;通常是方法或函数&#xff09;分离出来并独立测试&a…...

水箱高低水位浮球液位开关

水箱高低水位浮球液位开关概述 水箱高低水位浮球液位开关是一种用于监测和控制水箱中液位的自动化设备&#xff0c;它能够在水箱液位达到预设的高低限制时&#xff0c;输出开关信号&#xff0c;以控制水泵或电磁阀的开闭&#xff0c;从而维持水箱液位在一个安全的范围内。这类设…...

Autoware内容学习与初步探索(一)

0. 简介 之前作者主要是基于ROS2&#xff0c;CyberRT还有AutoSar等中间件完成搭建的。有一说一&#xff0c;这种从头开发当然有从头开发的好处&#xff0c;但是如果说绝大多数的公司还是基于现成的Apollo以及Autoware来完成的。这些现成的框架中也有很多非常好的方法。目前作者…...

【手写数据库内核组件】01 解析树的结构,不同类型的数据结构组多层的链表树,抽象类型统一引用格式

不同类型的链表 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章目录 不同类型…...

Pandas 进阶 —— 数据转换、聚合与可视化

引言 在数据分析的旅程中&#xff0c;Pandas 库提供了从数据转换到聚合再到可视化的全面解决方案。上篇我们掌握了数据的导入和清洗&#xff0c;本篇我们将探索如何通过 Pandas 对数据进行更高级的处理&#xff0c;包括数据转换、聚合分析以及可视化展示。 数据转换 数据转换…...

华为OD机试 - 来自异国的客人(Java 2024 D卷 100分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…...

期末上分站——计组(3)

复习题21-42 21、指令周期是指__C_。 A. CPU从主存取出一条指令的时间 B. CPU执行一条指令的时间 C. CPU从主存取出一条指令的时间加上执行这条指令的时间。 D. 时钟周期时间 22、微型机系统中外设通过适配器与主板的系统总线相连接&#xff0c;其功能是__D_。 A. 数据缓冲和…...

IDA*——AcWing 180. 排书

IDA* 定义 IDA*&#xff08;Iterative Deepening A*&#xff09;是一种结合了深度优先搜索&#xff08;DFS&#xff09;的递归深度限制特性和A搜索的启发式估价函数的搜索算法。它主要用于解决启发式搜索问题&#xff0c;尤其是当搜索空间很大或者搜索成本不确定时。 IDA* 是…...

【云计算】公有云、私有云、混合云、社区云、多云

公有云、私有云、混合云、社区云、多云 1.云计算的形态1.1 公有云1.2 私有云1.3 混合云1.4 社区云1.5 多云1.5.1 多云和混合云之间的关系1.5.2 多云的用途1.5.3 影子 IT 和多云1.5.4 优缺点 2.不同云形态的对比 1.云计算的形态 张三⾃⼰在家做饭吃&#xff0c;这是 私有云&…...

MySQL中的MVCC解析

MySQL中的MVCC解析 多版本并发控制是MySQL中实现高并发的一种关键技术。通过对数据进行多版本的管理&#xff0c;MVCC能够在保证数据一致性的同时&#xff0c;提高数据库的并发性能。本文将深入探讨MySQL中的MVCC机制&#xff0c;包括其原理、实现方式以及优势。 MVCC的原理 …...

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的生日聚会(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…...

初识STM32:芯片基本信息

STM32简介 STM32是ST公司基于ARM公司的Cortex-M内核开发的32位微控制器。 ARM公司是全球领先的半导体知识产权&#xff08;IP&#xff09;提供商&#xff0c;全世界超过95%的智能手机和平板电脑都采用ARM架构。 ST公司于1987年由意大利的SGS微电子与法国的Thomson半导体合并…...

Zabbix 配置PING监控

Zabbix PING监控介绍 如果需要判断机房的网络或者主机是否正常&#xff0c;这就需要使用zabbix ping&#xff0c;Zabbix使用外部命令fping处理ICMP ping的请求&#xff0c;在基于ubuntu APT方式安装zabbix后默认已存在fping程序。另外zabinx_server配置文件参数FpingLocation默…...

异常解决(三)-- Wandb fails with ServiceStartProcessError

原文链接&#xff1a;https://github.com/wandb/wandb/issues/5765 我的环境配置&#xff1a; Python3.8.16 Wandb0.17.4 在使用Wandb记录实验数据时&#xff0c; 报以下错误&#xff1a; ServiceStartProcessError: The wandb service process exited with 1. Ensure that s…...

Qt调用Matlab(一)

目录 1 概述2 创建Qt工程2.1 增加Matlab支持3 调用Matlab3.1 widget.h3.2 widget.cpp4 运行4.1 配置4.2 运行1 概述 MATLAB是MathWorks公司出品的商业数学软件,用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险管理、机器人,控制系统等领域…...

网络爬虫(二) 哔哩哔哩热榜高频词按照图片形状排列

我们有时候需要爬取结果生成为自定义的词云图 生成自定义的词云图通常需要以下步骤&#xff1a; 1. 爬取数据&#xff1a;使用爬虫工具或库&#xff0c;如requests、BeautifulSoup等&#xff0c;可以爬取网页、论坛、社交媒体等平台上的文本数据。 2. 数据预处理&#xff1a…...

MySQL 常见错误及解决方案

1. Too many connections 运行环境&#xff1a;Winows11、Phpstudy V8.1.1.3、MySQL 5.7.26 同一时间 MySQL 的连接数量有限制&#xff0c;当超过上限时将提示下面错误信息&#xff1a; 1040 - Too many connections 查看当前最大连接数 mysql> show variables like %max_…...

STM32 - 内存分区与OTA

最近搞MCU&#xff0c;发现它与SOC之间存在诸多差异&#xff0c;不能沿用SOC上一些技术理论。本文以STM L4为例&#xff0c;总结了一些STM32 小白入门指南。 标题MCU没有DDR&#xff1f; 是的。MCU并没有DDR&#xff0c;而是让代码存储在nor flash上&#xff0c;临时变量和栈…...

RAG理论:ES混合搜索BM25+kNN(cosine)以及归一化

接前一篇:RAG实践:ES混合搜索BM25+kNN(cosine) https://blog.csdn.net/Xin_101/article/details/140230948 本文主要讲解混合搜索相关理论以及计算推导过程, 包括BM25、kNN以及ES中使用混合搜索分数计算过程。 详细讲解: (1)ES中如何通过BM25计算关键词搜索分数; (2)…...

分享大厂对于缓存操作的封装

hello&#xff0c;伙伴们好久不见&#xff0c;我是shigen。发现有两周没有更新我的文章了。也是因为最近比较忙&#xff0c;基本是993了。 缓存大家再熟悉不过了&#xff0c;几乎是现在任何系统的标配&#xff0c;并引申出来很多的问题&#xff1a;缓存穿透、缓存击穿、缓存雪崩…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...