使用 Google Test (gtest) 进行单元测试及生成测试报告的完整流程手册
1. 环境准备
1.1 安装依赖
-
gtest:Google 测试框架
sudo apt-get install libgtest-dev # Ubuntu/Debian # 或手动下载并编译 cd /usr/src/gtest sudo cmake . sudo make sudo cp *.a /usr/lib
-
lcov:代码覆盖率工具
sudo apt-get install lcov
-
CMake:构建系统管理
sudo apt-get install cmake
1.2 项目结构示例
my_project/
├── CMakeLists.txt
├── src/
│ └── calculator.cpp
│ └── calculator.h
└── tests/
└── calculator_test.cpp
2. 编写单元测试用例(gtest)
2.1 测试用例编写规范
- 文件命名:
*_test.cpp
(如calculator_test.cpp
) - 测试类命名:
TestClassName
(如CalculatorTest
) - 测试函数命名:
TEST(TestCaseName, TestName)
(如TEST(CalculatorTest, Add_TwoNumbers)
)
2.2 示例测试代码
// tests/calculator_test.cpp
#include <gtest/gtest.h>
#include "calculator.h"
TEST(CalculatorTest, Add_TwoNumbers) {
Calculator calc;
EXPECT_EQ(calc.Add(2, 3), 5);
EXPECT_EQ(calc.Add(-1, 1), 0);
}
TEST(CalculatorTest, Multiply_Zero) {
Calculator calc;
EXPECT_EQ(calc.Multiply(5, 0), 0);
}
3. 配置 CMakeLists.txt
3.1 添加 gtest 依赖
# my_project/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(MyProject)
# 添加源文件
add_subdirectory(src)
# 配置测试
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
# 添加测试目标
add_executable(calculator_tests tests/calculator_test.cpp)
target_link_libraries(calculator_tests ${GTEST_LIBRARIES} pthread)
# 添加测试执行命令
add_test(NAME calculator_tests COMMAND calculator_tests)
3.2 启用代码覆盖率
# 在 CMakeLists.txt 中添加以下内容
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage")
4. 构建与执行测试
4.1 构建项目
mkdir build && cd build
cmake ..
make
4.2 执行测试
./calculator_tests
5. 生成代码覆盖率报告
5.1 使用 lcov 捕获覆盖率数据
# 初始化 lcov(清空旧数据)
lcov --directory . --zerocounters
# 捕获新覆盖率数据
lcov --capture --directory . --output-file coverage.info
# 排除第三方库和测试代码
lcov --remove coverage.info '*/tests/*' '*/usr/*' --output-file coverage_filtered.info
5.2 生成 HTML 报告
genhtml -o coverage_report coverage_filtered.info
5.3 查看报告
xdg-open coverage_report/index.html
6. 持续集成(CI)集成示例(GitHub Actions)
# .github/workflows/ci.yml
name: Unit Tests and Coverage
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: sudo apt-get install cmake g++ lcov
- name: Configure CMake
run: |
mkdir build
cd build
cmake ..
- name: Build and Test
run: |
cd build
make
ctest --output-on-failure
- name: Generate Coverage Report
run: |
cd build
lcov --directory . --zerocounters
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '*/tests/*' '*/usr/*' --output-file coverage_filtered.info
genhtml -o coverage_report coverage_filtered.info
- name: Upload Coverage Report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: build/coverage_report
7. 完整实例:计算器项目
7.1 项目代码(src/calculator.cpp)
#include "calculator.h"
int Calculator::Add(int a, int b) {
return a + b;
}
int Calculator::Multiply(int a, int b) {
return a * b;
}
7.2 项目头文件(src/calculator.h)
#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator {
public:
int Add(int a, int b);
int Multiply(int a, int b);
};
#endif
7.3 运行全流程
# 步骤 1:构建项目
cd build
cmake ..
make
# 步骤 2:执行测试
./calculator_tests
# 步骤 3:生成覆盖率报告
lcov --directory . --zerocounters
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '*/tests/*' '*/usr/*' --output-file coverage_filtered.info
genhtml -o coverage_report coverage_filtered.info
# 步骤 4:查看报告
xdg-open coverage_report/index.html
8. 最佳实践与注意事项
8.1 测试覆盖率阈值
- 在 CI 中设置覆盖率阈值(如
lcov
结合coveralls
或codecov
)。 - 示例:
lcov --list coverage_filtered.info | grep 'lines'
查看覆盖率。
8.2 排除非代码文件
- 在
lcov
命令中排除第三方库、测试代码和生成文件:lcov --remove coverage.info '*/tests/*' '*/vendor/*' --output-file coverage_filtered.info
8.3 多测试二进制文件处理
- 如果有多个测试二进制文件,需合并覆盖率数据:
lcov --add-tracefile test1.info --add-tracefile test2.info --output-file merged.info
8.4 持续集成报告存储
- 使用
codecov
或coveralls
上传覆盖率报告:bash <(curl -s https://codecov.io/bash) -f coverage_filtered.info
附录:常见问题
Q: 覆盖率报告显示 0%?
- 原因:未正确添加
--coverage
编译参数。 - 解决:在
CMakeLists.txt
中确保:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage")
Q: genhtml 生成的 HTML 为空?
- 原因:未正确捕获覆盖率数据。
- 解决:检查
lcov
命令是否覆盖了所有源文件路径。
通过以上步骤,团队成员可快速在大型项目中实现单元测试与覆盖率分析,并通过自动化工具提升代码质量。