“没有测试的代码重构不能称之为重构,它仅仅是垃圾代码的到处移动” ——Corey Haines
目录
前言
什么是单元测试?
单元测试的组成
单元测试的命名
单元测试的独立性
Google Test 单元测试的环境配置与使用
1. Ubuntu下安装 Google Test
2. 编写测试代码
3. 编译和运行
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 源码生成静态库:
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),编写测试代码。
示例测试代码:
#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++ 编译测试程序:
g++ -std=c++17 -isystem /usr/include/gtest -pthread test_add.cpp -lgtest -lgtest_main -o test_add
运行生成的可执行文件:
./test_add
4. 测试结果
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++ 中进行高效的单元测试。掌握单元测试的技巧,可以帮助开发者提高代码的可靠性与可维护性。
相关阅读
- Four-Second Test Runs – Corey Haines
- GoogleTest Primer | GoogleTest