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 ]; then
  echo "Tests failed!"
  exit 1
else
  echo "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_H

class 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
  - test

build_job:
  stage: build
  script:
    - mkdir build
    - cd build
    - cmake ..
    - make
  artifacts:
    paths:
      - build/CalculatorTest  # 假设测试可执行文件生成在这个路径下

test_job:
  stage: test
  script:
    - cd build
    - ./CalculatorTest  # 运行测试可执行文件
  dependencies:
    - build_job  # 依赖构建阶段的job
  only:
    - 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 ]; then
    echo "Tests failed!"
    exit 1
else
    echo "All tests passed!"
    exit 0
fi

在这个脚本中,我们切换到构建目录,运行测试可执行文件,并根据其退出状态检查测试是否成功。如果测试失败,脚本将输出错误信息并退出;如果测试成功,则输出成功信息并正常退出。

如果希望在GitLab CI/CD流水线中添加一个测试步骤,需要创建一个新的作业(job),该作业专门用于运行测试脚本(run_tests.sh)。这个作业应该位于构建(build)和部署(deploy)作业之间,以确保在尝试部署之前,软件已经通过了必要的测试。

以下是如何在您的YAML文件中添加测试脚本的一个示例:

stages:
  - build
  - test  # 新增的测试阶段
  - deploy

# ...(其他配置保持不变)

# 测试作业
test_job:
  stage: test
  dependencies:
    - 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具有访问和构建项目的适当权限。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

备忘笔记-工具:JetBrains友好工具安装配置

1、配置/脚本文件下载 1、校验地址&#xff1a;https://3.jetbra.in/ 打开选择可用链接&#xff0c;点击跳转可用页面。 2、下载文件 左上角点击下载jetbra.zip文件 下载对应全家桶软件版本号&#xff0c;版本号在对应卡票右上角可见。 2、安装包下载 官网地址&#xff1a…

Flask 基于wsgi源码启动流程

1. 点击 __call__ 进入到源码 2. 找到 __call__ 方法 return 执行的是 wsgi方法 3. 点击 wsgi 方法 进到 wsgi return 执行的是 response 方法 4. 点击response 方法 进到 full_dispatch_request 5. full_dispatch_request 执行finalize_request 方法 6. finalize_request …

Linux 下进程基本概念与状态

文章目录 一、进程的定义二、 描述进程-PCBtask_ struct内容分类 三、 进程状态 一、进程的定义 狭义定义&#xff1a;进程是正在运行的程序的实例&#xff08;an instance of a computer program that is being executed&#xff09;。广义定义&#xff1a;进程是一个具有一定…

IDEA使用tips(LTS✍)

一、查找项目中某个外部库依赖类的pom来源 1、显示图 2、导出Maven 项目依赖的可视化输出文件 3、点击要查找的目标类&#xff0c;项目中定位后复制依赖名称 4、在导出的依赖的可视化文件中搜索查找 5、综上得到&#xff0c;Around类来自于pom中的spring-boot-starter-aop:jar…

【shell编程】函数、正则表达式、文本处理工具

函数 系统函数 常见内置命令 echo打印输出 #!/bin/bash # 输出普通文本 echo "Hello, World!"# 输出变量值 name"Alice" echo "Hello, $name"# 输出带有换行符的文本 echo -n "Hello, " # -n 选项不输出换行 echo "World!&quo…

如何选择服务器

如何选择服务器 选择服务器时应考虑以下几个关键因素&#xff1a; 性能需求。根据网站的预期流量和负载情况&#xff0c;选择合适的处理器、内存和存储容量。考虑网站是否需要处理大量动态内容或高分辨率媒体文件。 可扩展性。选择一个可以轻松扩展的服务器架构&#xff0c;以便…

LeetCode 904.水果成篮

LeetCode 904.水果成篮 思路&#x1f9d0;&#xff1a; 求水果的最大数目&#xff0c;也就是求最大长度&#xff0c;我们是单调的向前求解&#xff0c;则能够想到使用滑动窗口进行解答&#xff0c;可以用hash表统计每个种类的个数&#xff0c;kinds变量统计当前种类&#xff0c…

初始Python篇(7)—— 正则表达式

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; Python 目录 正则表达式的概念 正则表达式的组成 元字符 限定符 其他字符 正则表达式的使用 正则表达式的常见操作方法 match方法的…

小程序免备案:快速部署与优化的全攻略

小程序免备案为开发者提供了便捷高效的解决方案&#xff0c;省去繁琐的备案流程&#xff0c;同时通过优化网络性能和数据传输&#xff0c;保障用户体验。本文从部署策略、应用场景到技术实现&#xff0c;全面解析小程序免备案的核心优势。 小程序免备案&#xff1a;快速部署与优…

L14.【LeetCode笔记】返回倒数第k个节点

目录 1.题目 2.分析 思路 代码 提交结果 1.题目 面试题 02.02. 返回倒数第 k 个节点 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 注意&#xff1a;本题相对原题稍作改动 示例&#xff1a; 输入&#xff1a; 1->2->3->4->5 和 …

深入解析 EasyExcel 组件原理与应用

✨深入解析 EasyExcel 组件原理与应用✨ 官方&#xff1a;EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网 在日常的 Java 开发工作中&#xff0c;处理 Excel 文件的导入导出是极为常见的需求。 今天&#xff0c;咱们就一起来深入了解一款非常实用的操作 Exce…

基于Java Springboot高校教室资源管理系统

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

k8s1.31版本最新版本集群使用容器镜像仓库Harbor

虚拟机 rocky9.4 linux master node01 node02 已部署k8s集群版本 1.31 方法 一 使用容器部署harbor (1) wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo yum -y install docker-ce systemctl enable docker…

C语言数据结构学习:循环队列

C语言 数据结构学习 汇总入口&#xff1a; C语言数据结构学习&#xff1a;[汇总] 1. 循环队列 队列的博客&#xff1a;C语言数据结构学习&#xff1a;队列 循环队列会预先定义最大队列空间&#xff0c;然后定义一个数组&#xff0c;通过队列头和队列尾指针分别指向开头和结尾&…

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 遍历对象的值 遍历…

小米note pro一代(leo)线刷、twrp、magisk、TODO: android源码编译

本文主要说android5 整体思路 android 5.1 twrp magisk Zygisk(Riru) Dreamland(xposed) Riru不支持android5.1, 因此只能选择Zygisk : 如果你正在使用 Android 5&#xff0c;你必须使用 Zygisk 因为 Riru 并不支持 Android 5. 基于magisk之上的xposed 其中提到的 作者…

自然语言处理: RAG优化之Embedding模型选型重要依据:mteb/leaderboard榜

本人项目地址大全&#xff1a;Victor94-king/NLP__ManVictor: CSDN of ManVictor git地址&#xff1a;https://github.com/opendatalab/MinerU 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新不易&#xff0c;希望走过路…

Redis 常用数据类型插入性能对比:循环插入 vs. 批量插入

Redis 是一款高性能的键值数据库&#xff0c;其支持多种数据类型&#xff08;String、Hash、List、Set、ZSet、Geo&#xff09;。在开发中&#xff0c;经常会遇到需要插入大量数据的场景。如果逐条插入&#xff0c;性能会显得较低&#xff0c;而采用 Pipeline 批量插入 能大幅提…

oneplus6线刷、trwp、magisk(apatch)、LSPosed、Shamiko、Hide My Applist

oneplus6线刷android10.0.1 oneplus6线刷包(官方android10.0.1)下载、线刷教程&#xff1a; OnePlus6-brick-enchilada_22_K_52_210716_repack-HOS-10_0_11-zip 启用开发者模式 设置 / 连续点击6次版本号 : 启用开发者模式设置/开发者模式/{打开 usb调试, 打开 网络adb调试,…

node.js中使用express.static()托管静态资源

express.static()定义 express.static(root, [options])是一个中间件函数&#xff0c;负责为Express应用提供静态资源服务。它允许你指定一个或多个目录作为静态资源的根目录&#xff0c;当客户端请求这些资源时&#xff0c;Express会查找并返回对应的文件。 安装express npm i…