C++小碗菜之二:软件单元测试

"没有测试的代码重构不能称之为重构,它仅仅是垃圾代码的到处移动" ------Corey Haines

目录

前言

什么是单元测试?

单元测试的组成

单元测试的命名

单元测试的独立性

[Google Test 单元测试的环境配置与使用](#Google Test 单元测试的环境配置与使用)

[1. Ubuntu下安装 Google Test](#1. Ubuntu下安装 Google Test)

[2. 编写测试代码](#2. 编写测试代码)

[3. 编译和运行](#3. 编译和运行)

[4. 测试结果](#4. 测试结果)

结束语

相关阅读


总阅读时间约为 10~15分钟。

前言

本文将主要介绍单元测试的相关基础知识、安装并使用Google Test进行一个简单例子的单元测试。

什么是单元测试?

单元测试是一小段代码,在特定上下文环境中,单元测试能够验证程序的一个"单元"是否按预期工作,确保单个函数或方法在不同输入下都能按预期产生正确的输出。

在大多数情况下,这个****"单元"****是函数、方法或类的某个方法。如果单元测试覆盖率非常高,就可以在很短的时间内,检查正在开发的系统的所有组件是否运行正常。

单元测试一般由开发人员自行完成。如果条件允许,单元测试代码的开发应与程序代码的开发同步进行

单元测试的组成

测试用例:每个测试通常由输入、预期输出和执行步骤组成。测试用例要覆盖不同的输入场景,包含正常情况和边界情况。

测试框架 :单元测试通常依赖于测试框架,框架提供了组织测试、执行测试和生成报告的工具。常见的 C++ 测试框架包括 Google Test、Catch2、Boost.Test 等。

断言:断言是测试框架提供的函数,用于验证代码的输出是否与预期结果一致。如EXPECT_EQ() 等。

在 Google Test 中,断言分为两种:

非致命断言(如 EXPECT_EQ):即使断言失败,测试仍会继续运行。

致命断言(如 ASSERT_EQ):断言失败会终止当前测试。

单元测试的命名

一个好的单元测试方法命名应该能够简洁、明确地表述它正在测试的内容。通常的命名格式是:

<功能/模块><测试条件><期望结果>()

· 功能或模块:测试的功能或模块,通常是类名或者方法名。例如 Add、GetUserName。

· 测试条件:描述特定条件或输入数据。例如 TwoPositiveNumbers、Zero、WhenUserIdIsValid。

· 期望结果:描述你期望测试的输出或行为。例如 ReturnsCorrectSum、ReturnsZero、ReturnsCorrectName。

单元测试的独立性

每个单元测试之间应该是独立的,不要编写"一个单元测试的输出是另一个测试单元的输入"的单元测试

Google Test 单元测试的环境配置与使用

1. Ubuntu下 安装 Google Test

使用包管理工具安装 Google Test(如 libgtest-dev)。

编译 Google Test 源码生成静态库:

bash 复制代码
sudo apt install libgtest-dev cmake
cd /usr/src/googletest
sudo cmake .
sudo make
sudo cp lib/*.a /usr/lib

2. 编写测试代码

创建一个 .cpp 文件(如 test_add.cpp),编写测试代码。

示例测试代码:

cpp 复制代码
#include <gtest/gtest.h>

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

// 测试套件:AdditionTests
TEST(AdditionTests, HandlesPositiveNumbers) {
    EXPECT_EQ(add(2, 3), 5);
}

TEST(AdditionTests, HandlesNegativeNumbers) {
    EXPECT_EQ(add(-2, -3), -5);
}

TEST(AdditionTests, HandlesMixedNumbers) {
    EXPECT_EQ(add(-2, 3), 1);
}

TEST(AdditionTests, HandlesZero) {
    EXPECT_EQ(add(0, 5), 5);
}

3. 编译和运行

使用 g++ 编译测试程序:

bash 复制代码
g++ -std=c++17 -isystem /usr/include/gtest -pthread test_add.cpp -lgtest -lgtest_main -o test_add

运行生成的可执行文件:

bash 复制代码
./test_add

4. 测试结果

css 复制代码
Running main() from ./googletest/src/gtest_main.cc
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from AdditionTests
[ RUN      ] AdditionTests.HandlesPositiveNumbers
[       OK ] AdditionTests.HandlesPositiveNumbers (0 ms)
[ RUN      ] AdditionTests.HandlesNegativeNumbers
[       OK ] AdditionTests.HandlesNegativeNumbers (0 ms)
[ RUN      ] AdditionTests.HandlesMixedNumbers
[       OK ] AdditionTests.HandlesMixedNumbers (0 ms)
[ RUN      ] AdditionTests.HandlesZero
[       OK ] AdditionTests.HandlesZero (0 ms)
[----------] 4 tests from AdditionTests (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test suite ran. (0 ms total)
[  PASSED  ] 4 tests.

结束语

通过本文的学习,我们了解了单元测试的基本概念及其重要性,尤其是如何使用 Google Test 在 C++ 中进行高效的单元测试。掌握单元测试的技巧,可以帮助开发者提高代码的可靠性与可维护性。

相关阅读

  1. Four-Second Test Runs -- Corey Haines
  2. GoogleTest Primer | GoogleTest
相关推荐
智慧地球(AI·Earth)2 分钟前
OpenAI for Countries:全球AI基础设施的“技术基建革命”
开发语言·人工智能·php
不学无术の码农5 分钟前
《Effective Python》第1章 Pythonic 思维总结——编写优雅、高效的 Python 代码
开发语言·python
双叶83637 分钟前
(C语言)超市管理系统(测试版)(指针)(数据结构)(二进制文件读写)
c语言·开发语言·数据结构·c++
PXM的算法星球39 分钟前
使用CAS操作实现乐观锁的完整指南
开发语言
TDengine (老段)1 小时前
基于 TSBS 标准数据集下 TimescaleDB、InfluxDB 与 TDengine 性能对比测试报告
java·大数据·开发语言·数据库·时序数据库·tdengine·iotdb
格林威1 小时前
Baumer工业相机堡盟工业相机的工业视觉是否可以在室外可以做视觉检测项目
c++·人工智能·数码相机·计算机视觉·视觉检测
追烽少年x1 小时前
C++11异步编程 --- async
c++
rylshe13142 小时前
在scala中sparkSQL连接mysql并添加新数据
开发语言·mysql·scala
小宋加油啊2 小时前
Mac QT水平布局和垂直布局
开发语言·qt·macos
MyhEhud2 小时前
kotlin @JvmStatic注解的作用和使用场景
开发语言·python·kotlin