C++ 测试与调试实战:保障代码质量与稳定性
核心目标
掌握 C++ 测试与调试的核心知识,确保代码质量与稳定性。我们将覆盖以下内容:
- 理解测试与调试的基本概念及方法
- 使用主流单元测试框架(Google Test、Catch2)
- 掌握集成测试策略,验证系统功能正确性
- 熟练使用 GDB 和 Visual Studio 调试器
- 培养测试驱动的开发思维
测试基础
测试分类
- 单元测试:验证单个函数或类的行为
- 集成测试:检查模块间的交互
- 系统测试:验证整个系统的功能
- 验收测试:确认是否满足用户需求
- 性能测试:评估系统性能指标
测试原则
- 尽早开始测试
- 覆盖所有关键场景
- 保持自动化
- 确保可重复执行
- 保持测试独立性
单元测试框架
Google Test
Google Test 是业界广泛使用的 C++ 单元测试框架,提供丰富的断言支持。
安装指南
# Ubuntu/Debian
sudo apt-get install libgtest-dev
# macOS (Homebrew)
brew install googletest
示例代码
#include <gtest/gtest.h>
#include "MyClass.h"
TEST(MyClassTest, ConstructorTest) {
MyClass obj;
EXPECT_EQ(obj.getValue(), 0);
}
TEST(MyClassTest, SetGetValueTest) {
MyClass obj;
obj.setValue(42);
EXPECT_EQ(obj.getValue(), 42);
}
// 更多测试用例...
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Catch2
Catch2 提供了更简洁的语法,适合快速编写测试。
安装指南
# Ubuntu/Debian
sudo apt-get install catch2
# macOS (Homebrew)
brew install catch2
示例代码
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
#include "MyClass.h"
TEST_CASE("MyClass Constructor Test", "[constructor]") {
MyClass obj;
REQUIRE(obj.getValue() == 0);
}
调试工具实战
GDB 调试器
Linux 环境下最常用的调试工具。
基本命令
# 编译时添加调试信息
g++ -g program.cpp -o program
# 启动 GDB
gdb program
常用指令包括 break(设置断点)、run(运行)、next(单步跳过)、step(单步进入)、print(打印变量)、backtrace(查看调用栈)。
调试示例
#include <iostream>
#include "MyClass.h"
int main() {
MyClass obj;
obj.setValue(42);
int result = obj.add(20);
std::cout << "结果:" << result << std::endl;
return 0;
}
Visual Studio 调试器
Windows 下强大的图形化调试环境,支持断点、变量监视和调用栈分析。
- 在代码行号旁点击设置断点。
- 按 F5 启动调试。
- 程序暂停后,通过窗口查看变量状态。
- 使用'继续'恢复执行。
集成测试
集成测试关注模块间的协作。常见策略包括自顶向下、自底向上以及三明治集成法。
示例
#include <gtest/gtest.h>
#include "Calculator.h"
#include "Parser.h"
TEST(IntegrationTest, CalculateTest) {
Calculator calculator;
Parser parser;
std::string expression = "10 + 20";
int result = parser.parse(expression);
EXPECT_EQ(result, 30);
}
综合案例:计算器项目
项目结构
CalculatorProject/
├── include/
│ ├── Calculator.h
│ └── Parser.h
├── src/
│ ├── Calculator.cpp
│ ├── Parser.cpp
│ └── main.cpp
├── tests/
│ ├── CalculatorTest.cpp
│ ├── ParserTest.cpp
│ └── IntegrationTest.cpp
└── CMakeLists.txt
核心实现
Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator {
public:
static int add(int a, int b);
static int subtract(int a, int b);
static int multiply(int a, int b);
static int divide(int a, int b);
};
#endif
Calculator.cpp
#include "Calculator.h"
#include <stdexcept>
int Calculator::add(int a, int b) { return a + b; }
int Calculator::subtract(int a, int b) { return a - b; }
int Calculator::multiply(int a, int b) { return a * b; }
int Calculator::divide(int a, int b) {
if (b == 0) throw std::invalid_argument("除数不能为零");
return a / b;
}
Parser.cpp
#include "Parser.h"
#include <sstream>
int Parser::parse(const std::string& expression) {
std::istringstream iss(expression);
int a, b; char op;
iss >> a >> op >> b;
switch(op) {
case '+': return Calculator::add(a, b);
case '-': return Calculator::subtract(a, b);
case '*': return Calculator::multiply(a, b);
case '/': return Calculator::divide(a, b);
default: throw std::invalid_argument("无效的运算符");
}
}
main.cpp
#include <iostream>
#include "Parser.h"
int main() {
Parser parser;
try {
std::string expression;
std::cout << "请输入表达式(例如:10 + 20): ";
std::getline(std::cin, expression);
int result = parser.parse(expression);
std::cout << "结果:" << result << std::endl;
} catch (const std::exception& e) {
std::cerr << "错误:" << e.what() << std::endl;
return 1;
}
return 0;
}
构建与测试
mkdir -p build && cd build
cmake ..
make
ctest
总结与练习
本章涵盖了测试分类、Google Test/Catch2 框架、GDB/VS 调试器以及集成测试实践。建议读者尝试以下练习以巩固技能:
- 使用 Google Test 测试链表数据结构。
- 利用 GDB 排查内存泄漏问题。
- 使用 Visual Studio 调试多线程程序。
- 用 Catch2 测试自定义类功能。
- 为银行账户系统编写集成测试。
进阶方向可关注 Google Mock 模拟框架、Google Benchmark 性能测试、gcov 覆盖率分析、Clang Static Analyzer 静态检查以及 GitHub Actions 持续集成自动化。


