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流水线是一个强大的自动化部署和测试工具,它允许开发者在代码提交时自动执行一系列任务。流水线通常分为以下几个阶段:

  1. 构建(build)阶段
    在 GitLab CI/CD 流水线的构建阶段,主要任务是将 C++ 项目的代码进行编译和构建,生成可执行文件或库。这个阶段为后续的测试和部署阶段提供了基础。通过将源代码转化为可执行的形式,确保代码可以在不同的环境中运行。构建阶段的作用在于,它能够及时发现编译错误和依赖问题,避免在后续阶段浪费时间。如果构建阶段出现问题,可以快速定位并解决,提高开发效率。

  2. 测试(test)阶段
    在测试阶段,使用 GTest 具有重要意义。GTest(Google Test)是一个强大的 C++ 测试框架,它提供了丰富的断言和测试工具,可以对 C++ 项目进行高效的单元测试、集成测试等。在这个阶段,通过运行各种测试用例,可以确保代码的功能正常,及时发现潜在的问题。使用 GTest 可以提高测试的覆盖率和准确性,增强代码的可靠性。同时,结合 GitLab CI/CD,可以自动执行测试,提高测试的效率和一致性。在测试阶段,可以根据项目的需求,编写不同类型的测试用例,如功能测试、性能测试等,以全面验证代码的质量。

  3. 部署(deploy)阶段
    部署阶段的流程通常包括将构建好的代码部署到生产环境或其他目标环境中。首先,需要确保构建和测试阶段都成功完成,没有出现错误。然后,可以使用自动化工具或脚本来将代码部署到目标环境。部署的目标是使代码能够在实际环境中运行,为用户提供服务。在部署阶段,需要注意配置管理、环境一致性等问题,确保部署的顺利进行。同时,还可以进行一些额外的验证和监控,以确保部署后的系统稳定运行。

三、C++项目中使用 GTest 的步骤

  1. GTest 安装

    • 从GitHub下载GTest的发布版本。
    • 在Linux下,可以使用包管理工具(如apt-get)安装,或者从源代码编译安装。
    • 在Windows下,可以通过MSYS2、vcpkg等工具进行安装。
    • 在macOS下,可以使用Homebrew进行安装。
  2. 编写测试用例

    • 函数测试用例示例

      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类的默认设置。

  3. 运行测试用例
    使用gtest命令运行所有测试用例,例如:

    ./your_test_executable
    

    不同的断言宏如EXPECT_EQASSERT_TRUE等用于检查测试结果,确保代码行为符合预期。

  4. 运行测试用例
    以下是一个完整的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分支上运行

在这个配置文件中,我们定义了两个阶段:buildtestbuild_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具有访问和构建项目的适当权限。

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

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

相关文章

查询mysql用户信息及授权

SELECT user, host, account_locked, password_expired, password_last_changed, password_lifetime FROM mysql.user;user: 用户名。 host: 用户允许连接的主机。 account_locked: 账户是否被锁定。 password_expired: 密码是否已过期。 password_last_changed: 密码上…

算法模板2:位运算+离散化+区间合并

文章目录 1.6 位运算**位运算的常见应用**1.7 离散化**经典离散化题目例子****1. 区间合并和覆盖长度问题****2. 区间查询与修改****3. 动态求第 K 小值****4. 区间最大重叠次数****5. 动态逆序对计数****6. 二维区间问题****7. 模拟车流/时间段事件****8. 区间众数统计** **具…

【淘汰9成NLP面试者的高频面题】LSTM中的tanh和sigmoid分别用在什么地方?为什么?

博客主页&#xff1a; [青松] 本文专栏: NLP 大模型百面百过 【淘汰9成NLP面试者的高频面题】LSTM中的tanh和sigmoid分别用在什么地方&#xff1f;为什么&#xff1f; 重要性&#xff1a;★★★ &#x1f4af; 本题主要考察面试者对以下问题的理解&#xff1a; ① 数据特征和模…

【中间件】Redis

一、什么是Redis Redis是一个开源&#xff08;BSD许可&#xff09;&#xff0c;内存存储的数据结构服务器&#xff0c;可用作数据库&#xff0c;高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合&#xff0c;位图&#xff0c;hyperloglogs等数据类型。内置…

Python爬取豆瓣电影全部分类数据并存入数据库

在当今数字化的时代&#xff0c;网络上丰富的影视资源信息吸引着众多开发者去挖掘和利用。今天&#xff0c;我就来和大家分享一段有趣的代码&#xff0c;它能够从豆瓣电影平台获取相关数据并存储到数据库中哦。 结果展示&#xff08;文末附完整代码&#xff09;&#xff1a; 目…

YOLOv11(Ultralytics)视频选定区域目标统计计数及跟踪

在计算机视觉的众多应用场景中&#xff0c;对特定区域的目标进行检测、跟踪与计数是一个常见且重要的需求。无论是在智慧交通中统计通过特定路口的车辆数量&#xff0c;还是在零售分析中追踪进入特定区域的顾客行为&#xff0c;这一功能都发挥着不可或缺的作用。 随着深度学习…

数据结构与算法——1120——时间空间效率问题求边界值

目录 1、效率问题 1、时间复杂度 1、O(1) 2、O(n) 3、O(n) 或O(n*log2n)——n倍的log以2为底n的对数 例题 4、O(n) 2、空间复杂度 3、数组和链表 2、面试题之求边界值 题目 解答 &#xff08;1&#xff09;-i &#xff08;2&#xff09;~i &#xff08;3&#x…

第三十九篇 ShuffleNet V1、V2模型解析

摘要 ShuffleNet V1 ShuffleNet V1是由旷视科技&#xff08;Megvii&#xff0c;又称Face&#xff09;在2017年底提出的一种轻量级卷积神经网络架构。该网络专为移动设备和边缘计算环境设计&#xff0c;旨在以较低的计算资源实现高效的图像分类和其他计算机视觉任务。 特点与…

本地推流,服务器拉流全流程

本地推流&#xff0c;服务器拉流全流程 环境准备&#xff1a;准备一台服务器&#xff0c;其中openssl最好为1.1.1版本&#xff08;可以直接使用ubuntu20.04操作系统&#xff09; 服务器拉流 1、 安装环境依赖 sudo apt-get update sudo apt-get install unzip sudo apt-get…

【第八课】Rust中的函数与方法

目录 前言 函数指针 函数当作另一个函数的参数 函数当作另一个函数的返回值 闭包 方法 关联函数 总结 前言 在前面几课中&#xff0c;我们都或多或少的接触到了rust中的函数&#xff0c;rust中的函数和其他语言的并没有什么不同&#xff0c;简单的语法不在这篇文章中赘…

详解Qt之QtMath Qt数学类

文章目录 QtMath详解前言QtMath简介QtMath中的函数1. 三角函数1.1 qSin1.2 qCos 2. 指数与对数函数2.1 qExp2.2 qLn 3. 幂运算与平方根3.1 qPow3.2 qSqrt QtMath的优势1. 一致性与跨平台支持2. 与Qt生态系统集成3. 简洁性 总结 QtMath详解 前言 在C的开发中&#xff0c;数学运…

基于Java Springboot海洋馆预约系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

产业用机器人中的旋转花键若损伤有何影响?

旋转花键在产业用机器人中是关键的组件之一&#xff0c;如果机器人中的旋转花键损坏&#xff0c;会对机器人的运行和性能产生一定影响。以下是可能的影响&#xff1a; 1、功能受限&#xff1a;旋转花键用于连接两个旋转部件&#xff08;例如电机轴和传动轴&#xff09;&#xf…

MySQL-- 数据类型

1. 常⽤数据类型分类 我们在学习JAVA语言⾯向对象软件开发的过程中&#xff0c;通常会先进⾏需求分析从⽽得到类和属性&#xff0c;类是⾯向对象中的概念&#xff0c;对应到数据库中的概念就是实体&#xff0c;类中的属性对应实体中的属性。实体通常以表的形式存在&#xff0c…

CLIP-Adapter: Better Vision-Language Models with Feature Adapters 论文解读

abstract 大规模对比视觉-语言预训练在视觉表示学习方面取得了显著进展。与传统的通过固定一组离散标签训练的视觉系统不同&#xff0c;(Radford et al., 2021) 引入了一种新范式&#xff0c;该范式在开放词汇环境中直接学习将图像与原始文本对齐。在下游任务中&#xff0c;通…

百度在下一盘大棋

这两天世界互联网大会在乌镇又召开了。 我看到一条新闻&#xff0c;今年世界互联网大会乌镇峰会发布“2024 年度中国互联网企业创新发展十大典型案例”&#xff0c;百度文心智能体平台入选。 这个智能体平台我最近也有所关注&#xff0c;接下来我就来讲讲它。 百度在下一盘大棋…

RabbitMQ4:work模型

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

基于SpringBoot的数据结构系统设计与实现(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

100.【C语言】数据结构之二叉树的堆实现(顺序结构) 1

目录 1.顺序结构 2.示意图 ​编辑 从物理结构还原为逻辑结构的方法 3.父子节点编号的规律 4.顺序存储的前提条件 5.堆的简介 堆的定义 堆的两个重要性质 小根堆和大根堆 6.堆的插入 7.堆的实现及操作堆的函数 堆的结构体定义 堆初始化函数HeapInit 堆插入元素函…

Mac 环境变量配置基础教程

MacOS 下一般配置有多个 Shell&#xff0c;如 Bash、ZSH 等&#xff0c;不同的 Shell 其创建 Terminal 时使用的环境变量配置文件也不尽相同&#xff0c;但一般都会读取并执行脚本文件 /etc/profile 来加载系统级环境变量&#xff0c;而用户级别环境变量&#xff0c;一般都会在…