C++自动化测试:GTest 与 GitLab CI/CD 的完美融合
在现代软件开发中,自动化测试是保证代码质量和稳定性的关键手段。对于C++项目而言,自动化测试尤为重要,它能有效捕捉代码中的潜在缺陷,提高代码的可维护性和可靠性。本文将重点介绍如何在C++项目中结合使用Google Test(GTest)和GitLab CI/CD,特别是通过提供详细的脚本示例,展示如何实现高效的自动化测试流程。
一、GTest 简介
Google Test(GTest)是Google开发的一个C++测试框架,以其跨平台兼容性、丰富的断言宏、易于使用以及强大的功能而广受欢迎。GTest支持多种测试类型,包括单元测试、异常测试、死亡测试等,并且提供了灵活的测试套件和测试用例管理机制,使得编写和维护测试代码变得简单高效。

二、GitLab CI/CD 流水线概述
GitLab CI/CD流水线是一个强大的自动化部署和测试工具,它允许开发者在代码提交时自动执行一系列任务。流水线通常分为以下几个阶段:
-
构建(build)阶段
在 GitLab CI/CD 流水线的构建阶段,主要任务是将 C++ 项目的代码进行编译和构建,生成可执行文件或库。这个阶段为后续的测试和部署阶段提供了基础。通过将源代码转化为可执行的形式,确保代码可以在不同的环境中运行。构建阶段的作用在于,它能够及时发现编译错误和依赖问题,避免在后续阶段浪费时间。如果构建阶段出现问题,可以快速定位并解决,提高开发效率。 -
测试(test)阶段
在测试阶段,使用 GTest 具有重要意义。GTest(Google Test)是一个强大的 C++ 测试框架,它提供了丰富的断言和测试工具,可以对 C++ 项目进行高效的单元测试、集成测试等。在这个阶段,通过运行各种测试用例,可以确保代码的功能正常,及时发现潜在的问题。使用 GTest 可以提高测试的覆盖率和准确性,增强代码的可靠性。同时,结合 GitLab CI/CD,可以自动执行测试,提高测试的效率和一致性。在测试阶段,可以根据项目的需求,编写不同类型的测试用例,如功能测试、性能测试等,以全面验证代码的质量。 -
部署(deploy)阶段
部署阶段的流程通常包括将构建好的代码部署到生产环境或其他目标环境中。首先,需要确保构建和测试阶段都成功完成,没有出现错误。然后,可以使用自动化工具或脚本来将代码部署到目标环境。部署的目标是使代码能够在实际环境中运行,为用户提供服务。在部署阶段,需要注意配置管理、环境一致性等问题,确保部署的顺利进行。同时,还可以进行一些额外的验证和监控,以确保部署后的系统稳定运行。
三、C++项目中使用 GTest 的步骤
-
GTest 安装
- 从GitHub下载GTest的发布版本。
- 在Linux下,可以使用包管理工具(如apt-get)安装,或者从源代码编译安装。
- 在Windows下,可以通过MSYS2、vcpkg等工具进行安装。
- 在macOS下,可以使用Homebrew进行安装。
-
编写测试用例
-
函数测试用例示例:
TEST(FooTest, HandlesZeroInput) {EXPECT_EQ(Foo(0), 0); }这个测试用例验证了
Foo函数在输入为0时的行为。 -
类测试用例示例:
class ConfigureTest : public ::testing::Test { protected:void SetUp() override {config_ = new Configure();}void TearDown() override {delete config_;}Configure* config_; };TEST_F(ConfigureTest, DefaultSettings) {EXPECT_EQ(config_->GetSetting("default"), "value"); }这个测试类验证了
Configure类的默认设置。
-
-
运行测试用例
使用gtest命令运行所有测试用例,例如:./your_test_executable不同的断言宏如
EXPECT_EQ、ASSERT_TRUE等用于检查测试结果,确保代码行为符合预期。 -
运行测试用例
以下是一个完整的run_tests.sh脚本示例,用于在GitLab CI/CD中运行GTest测试用例:
#!/bin/bash# 切换到构建目录
cd /path/to/your/build/directory# 运行测试可执行文件
./your_test_executable# 检查测试是否成功
if [ $? -ne 0 ]; thenecho "Tests failed!"exit 1
elseecho "All tests passed!"
fi
关键代码解释:
cd /path/to/your/build/directory:切换到包含测试可执行文件的目录。./your_test_executable:运行测试可执行文件。if [ $? -ne 0 ]; then ... fi:检查上一个命令的退出状态,如果不为0(表示测试失败),则输出错误信息并退出脚本。
四、具体示例
以下提供更具体的示例,这些示例将展示如何在C++项目中使用Google Test(GTest)编写测试用例,并将其与GitLab CI/CD流水线结合使用。
1. GTest测试用例示例
假设我们有一个简单的C++类Calculator,它有一个加法函数Add。我们可以为这个函数编写一个GTest测试用例。
// Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_Hclass Calculator {
public:int Add(int a, int b);
};#endif // CALCULATOR_H// Calculator.cpp
#include "Calculator.h"int Calculator::Add(int a, int b) {return a + b;
}// CalculatorTest.cpp
#include <gtest/gtest.h>
#include "Calculator.h"TEST(CalculatorTest, HandlesPositiveInput) {Calculator calc;EXPECT_EQ(calc.Add(1, 2), 3);EXPECT_EQ(calc.Add(10, 20), 30);
}TEST(CalculatorTest, HandlesZeroInput) {Calculator calc;EXPECT_EQ(calc.Add(0, 0), 0);EXPECT_EQ(calc.Add(5, 0), 5);
}TEST(CalculatorTest, HandlesNegativeInput) {Calculator calc;EXPECT_EQ(calc.Add(-1, -1), -2);EXPECT_EQ(calc.Add(-1, 1), 0);
}int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
在这个示例中,我们定义了三个测试用例来验证Calculator类的Add函数。每个测试用例都使用EXPECT_EQ宏来检查函数的输出是否与预期值相等。
2. GitLab CI/CD流水线配置示例
以下是一个简单的GitLab CI/CD .gitlab-ci.yml配置文件示例,用于构建和运行上述GTest测试用例。
stages:- build- testbuild_job:stage: buildscript:- mkdir build- cd build- cmake ..- makeartifacts:paths:- build/CalculatorTest # 假设测试可执行文件生成在这个路径下test_job:stage: testscript:- cd build- ./CalculatorTest # 运行测试可执行文件dependencies:- build_job # 依赖构建阶段的jobonly:- main # 只在main分支上运行
在这个配置文件中,我们定义了两个阶段:build和test。build_job负责编译项目,生成测试可执行文件,并将其作为构建产物保存。test_job依赖build_job,负责运行测试可执行文件,并验证测试结果。
3. run_tests.sh脚本示例
虽然GitLab CI/CD流水线可以直接在script部分运行测试可执行文件,但有时我们可能希望使用一个单独的脚本来运行测试。以下是一个简单的run_tests.sh脚本示例。
#!/bin/bash# 切换到构建目录
cd /path/to/your/project/build# 运行测试可执行文件
./CalculatorTest# 检查测试是否成功
if [ $? -ne 0 ]; thenecho "Tests failed!"exit 1
elseecho "All tests passed!"exit 0
fi
在这个脚本中,我们切换到构建目录,运行测试可执行文件,并根据其退出状态检查测试是否成功。如果测试失败,脚本将输出错误信息并退出;如果测试成功,则输出成功信息并正常退出。
如果希望在GitLab CI/CD流水线中添加一个测试步骤,需要创建一个新的作业(job),该作业专门用于运行测试脚本(run_tests.sh)。这个作业应该位于构建(build)和部署(deploy)作业之间,以确保在尝试部署之前,软件已经通过了必要的测试。
以下是如何在您的YAML文件中添加测试脚本的一个示例:
stages:- build- test # 新增的测试阶段- deploy# ...(其他配置保持不变)# 测试作业
test_job:stage: testdependencies:- build_job # 依赖于构建作业,确保测试运行的是最新的构建script:- # 运行测试名为'run_tests.sh'的脚本。- ./run_tests.sh# 如果测试失败,您可能希望流水线停止继续执行。# 使用'allow_failure: false'(默认行为)来确保测试失败时流水线失败。# 如果您想在测试失败时仍然继续流水线,可以使用'allow_failure: true'。allow_failure: false# 只有在特定的分支或标签上运行时,才包含此作业(可选)。only:- main # 或者您希望运行测试的任何其他分支# 使用特定的运行器标签(可选)。tags:- kubernetes-linux-runner-test # 或者任何适合运行测试的标签# ...(其他作业保持不变,如build_job和deploy_job)
请注意,上述示例中的路径和文件名可能需要根据您的实际项目结构进行调整。此外,您还需要确保您的 GitLab CI/CD Runner具有访问和构建项目的适当权限。
相关文章:
C++自动化测试:GTest 与 GitLab CI/CD 的完美融合
在现代软件开发中,自动化测试是保证代码质量和稳定性的关键手段。对于C项目而言,自动化测试尤为重要,它能有效捕捉代码中的潜在缺陷,提高代码的可维护性和可靠性。本文将重点介绍如何在C项目中结合使用Google Test(GTe…...
vscode连接远程开发机报错
远程开发机更新,vscode连接失败 报错信息 "install" terminal command done Install terminal quit with output: Host key verification failed. Received install output: Host key verification failed. Failed to parse remote port from server ou…...
神经网络12-Time-Series Transformer (TST)模型
Time-Series Transformer (TST) 是一种基于 Transformer 架构的深度学习模型,专门用于时序数据的建模和预测。TST 是 Transformer 模型的一个变种,针对传统时序模型(如 RNN、LSTM)在处理长时间依赖、复杂数据关系时的限制而提出的…...
IDEA 2024安装指南(含安装包以及使用说明 cannot collect jvm options 问题 四)
汉化 setting 中选择插件 完成 安装出现问题 1.可能是因为之前下载过的idea,找到连接中 文件,卸载即可。...
Fakelocation Server服务器/专业版 Centos7
前言:需要Centos7系统 Fakelocation开源文件系统需求 Centos7 | Fakelocation | 任务一 更新Centos7 (安装下载不再赘述) sudo yum makecache fastsudo yum update -ysudo yum install -y kernelsudo reboot//如果遇到错误提示为 Another app is curre…...
oracle的静态注册和动态注册
oracle的静态注册和动态注册 静态注册: 静态注册 : 指将实例的相关信息手动告知 listener 侦 听 器 , 可以使用netmgr,netca,oem 以及直接 vi listener.ora 文件来实现静态注册,在动态注册不稳定时使用,特点是:稳定&…...
机器翻译基础与模型 之四:模型训练
1、开放词表 1.1 大词表和未登陆词问题 理想情况下,机器翻译应该是一个开放词表(Open Vocabulary)的翻译任务。也就是,无论测试数据中包含什么样的词,机器翻译系统都应该能够正常翻译。 现实的情况是即使不断扩充词…...
Vue——响应式数据,v-on,v-bind,v-if,v-for(内含项目实战)
目录 响应式数据 ref reactive 事件绑定指令 v-on v-on 鼠标监听事件 v-on 键盘监听事件 v-on 简写形式 属性动态化指令 v-bind iuput标签动态属性绑定 img标签动态属性绑定 b标签动态属性绑定 v-bind 简写形式 条件渲染指令 v-if 遍历指令 v-for 遍历对象的值 遍历…...
ceph 18.2.4二次开发,docker镜像制作
编译环境要求 #需要ubuntu 22.04版本 参考https://docs.ceph.com/en/reef/start/os-recommendations/ #磁盘空间最好大于200GB #内存如果小于100GB 会有OOM的情况发生,需要重跑 目前遇到内存占用最高为92GB替换阿里云ubuntu 22.04源 将下面内容写入/etc/apt/sources.list 文件…...
产品经理的项目管理课
各位产品经理,大家下午好,今天我给大家分享的主题是“产品经理如何做好项目管理”。 其实,我是不想分享这个主题的,是因为在周会中大家投票对这个议题最感兴趣,11个同学中有7个投了这个主题,所以才有了这次…...
Linux 下的 AWK 命令详细指南与示例
目录 简介AWK 的主要特性基本语法示例1. 打印文件的所有行2. 打印特定字段3. 打印匹配模式的行4. 基于条件过滤并打印5. 使用内置变量6. 执行算术运算7. 字符串操作8. 使用 BEGIN 和 END 块9. 处理分隔符文件 高级功能自定义脚本使用外部变量 总结 简介 AWK 是 Linux 中功能强…...
FPGA经验谈系列文章——8、复位的设计
前言 剑法往往有着固定的招式套路,而写代码似乎也存在类似的情况。不知从何时起,众多 FPGA 工程师们在编写代码时开启了一种关于 always 语句块的流行写法,那就是: always @(posedge i_clk or negedge i_rstn) 就笔者所经历的诸多项目以及所接触到的不少工程师而言,大家在…...
C#里怎么样实现操作符重载?
C#里怎么样实现操作符重载? 一般情况,都是表示某种类型的类时,才会使用到操作符重载。 比如实现一个复数类。 在C#中,重载运算符是通过在类或结构中定义特殊的方法来实现的,这些方法的名称是operator关键字后跟要重载的运算符。例如,要重载+运算符,可以定义一个名为op…...
项目实战:Vue3开发一个购物车
这段HTML代码实现了一个简单的购物车实战小项目的前端页面,结合了Vue.js框架来实现数据响应式和交互逻辑。页面展示了购物车中的商品项,每个商品项有增减数量的按钮,并且能显示商品总数以及目前固定为0元的商品总价和总价计算。 【运用响应式…...
Oracle SQL*Plus中的SET VERIFY
在 Oracle SQL*Plus 中,SET VERIFY ON 和 SET VERIFY OFF 是两个用于控制命令执行前后显示变量值的命令。这些命令主要用于调试和验证 SQL 脚本中的变量替换情况。 一、参数说明 1.1 SET VERIFY ON 作用:启用变量替换的验证功能。当启用时,S…...
Spring AI 框架使用的核心概念
一、模型(Model) AI 模型是旨在处理和生成信息的算法,通常模仿人类的认知功能。通过从大型数据集中学习模式和见解,这些模型可以做出预测、文本、图像或其他输出,从而增强各个行业的各种应用。 AI 模型有很多种&…...
二叉树路径相关算法题|带权路径长度WPL|最长路径长度|直径长度|到叶节点路径|深度|到某节点的路径非递归(C)
带权路径长度WPL 二叉树的带权路径长度(WPL)是二叉树所有叶节点的带权路径长度之和,给定一棵二叉树T,采用二叉链表存储,节点结构为 其中叶节点的weight域保存该节点的非负权值,设root为指向T的根节点的指针,设计求W…...
前端:JavaScript (学习笔记)【2】
目录 一,数组的使用 1,数组的创建 [ ] 2,数组的元素和长度 3,数组的遍历方式 4,数组的常用方法 二,JavaScript中的对象 1,常用对象 (1)String和java中的Stri…...
[面试]-golang基础面试题总结
文章目录 panic 和 recover**注意事项**使用 pprof、trace 和 race 进行性能调试。**Go Module**:Go中new和make的区别 Channel什么是 Channel 的方向性?如何对 Channel 进行方向限制?Channel 的缓冲区大小对于 Channel 和 Goroutine 的通信有…...
【案例】泛微.齐业成助力北京中远大昌汽车实现数电票全流程管理
中远大昌统一发票共享平台上线三个多月以来,实现: 5000份 60000元 发票开具 成本节约 客户简介及需求分析 北京中远大昌汽车服务有限公司(以下简称“中远大昌”)成立于2002年,是中远海运集团所属香远(北…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
