使用GTest进行单元测试的简明指南

我们在开发中常会遇到这样的情况:一个函数写完了,运行程序看起来没问题,就算“搞定”了。

但是…

如果你给它传入一个非法参数?别人修改了它的依赖逻辑?

如果你不管它们,那么这些被遗忘在角落“潜在问题”以后可能就会出 bug。

于是,单元测试就成为写稳健代码的利器。

但是,许多开发者因时间压力或认为集成测试足够而抗拒单元测试。

因此,本文想做的,就是用一个小例子告诉你:

原来写单元测试并不难,哪怕你从没接触过GTest,跟着做一遍你就知道它的价值。

GTest简介

Google Test (GTest) 是 Google 出品的 C++ 单元测试框架,具备以下特点:

  • 易用的断言机制:比如 EXPECT_EQ, ASSERT_TRUE
  • 自动发现测试用例和报告结果
  • 支持测试夹具、参数化测试等高级功能
  • 与生产代码分离,编译独立

它是目前 C++ 社区最主流的单元测试框架之一。

单元测试示例

接下来,我们从零开始构建一个简单的单元测试示例。(代码不用复制,文末有工程链接)

项目结构

project/
├── build
├── CMakeLists.txt
├── include
│   └── my_math.h
├── src
│   ├── CMakeLists.txt
│   └── my_math.cc
├── third_party
│   └── googletest
└── unit_test
    ├── CMakeLists.txt
    └── my_math_test.cc

为了更加直观的表现对GTest的使用,这里手动下载GTest源码,然后将解压出来的googletest拷贝到third_party中使用。

也可以使用FetchContent等方式,有兴趣的可以深入研究下。

核心代码

include/my_math.h

#pragma once

int Add(int a, int b);

src/my_math.cc

#include "my_math.h"

int Add(int a, int b) {
    return a + b;
}

测试代码

unit_test/my_math_test.cc

#include <gtest/gtest.h>
#include "my_math.h"

TEST(MyMathTest, AddWorks) {
    // 判断计算结果是否等于5
    EXPECT_EQ(Add(2, 3), 5);
    
    // 判断计算结果是否等于0
    EXPECT_EQ(Add(-1, 1), 0);
}

CMake配置详解

顶层CMakeLists.txt

cmake_minimum_required(VERSION 3.14)
project(unit_test_demo)

set(CMAKE_CXX_STANDARD 17)

# 设置GTest版本
set(GOOGLETEST_VERSION "1.17.0" CACHE STRING "GTest version")

# 添加源码
add_subdirectory(src)

# 添加测试
enable_testing()

# 添加GTest源码
add_subdirectory(third_party/googletest)

# 添加测试代码
add_subdirectory(unit_test)

src/CMakeLists.txt

# 将my_math.cc编译为静态库,待测
add_library(my_math my_math.cc)

target_include_directories(my_math PUBLIC ${PROJECT_SOURCE_DIR}/include)

unit_test/CMakeLists.txt

# 创建测试可执行文件
add_executable(math_test my_math_test.cc)

# 链接gtest_main和待测试的my_math库
target_link_libraries(math_test
  gtest_main
  my_math
)

# 加载 GTest 模块并注册测试
include(GoogleTest)
gtest_discover_tests(math_test)

构建与执行测试

构建项目

cd project
mkdir build && cd build
cmake ..  # 生成构建系统
make      # 编译项目及测试

运行测试

直接运行测试程序

unit_test/math_test

示例输出:
在这里插入图片描述

也可以直接执行ctest命令

以上就是搭建一个简单单元测试环境的过程。

后面我们可以在这个基础上增添功能,进行更加复杂的测试,比如代码覆盖率、Mock等。

结语

写单元测试,不是为了形式主义,不是为了指标,而是为了:

  • 把 bug 扼杀在最早期,而不是等上线再翻车
  • 给自己重构的勇气
  • 给团队传递信任和文档
  • 满足 ASPICE 等流程认证要求

希望本文能成为你 GTest 入门的起点~

代码仓库: https://github.com/LeafTime/GTest

本文首发于微信公众号《Linux在秋名山》,欢迎大家关注~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux在秋名山

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值