C++ 测试体系

一个工程级测试体系根据开发阶段通常分为以下几个阶段:

  • 单元测试
    • 对象:函数/类/模块
    • 目标:逻辑正确性
  • 集成测试
    • 对象:模块之间的协作
    • 目标:接口是否正确
  • 系统测试
    • 对象:整个程序
    • 目标:功能是否完整
  • 验收测试
    • 对象:业务需求
    • 目标:是否符合产品预期

每个阶段可能用到的测试方法和工具大概如下:

  • 静态测试
    • 静态分析:clang-tidy
    • 编译错误检查
  • 动态测试
    • 输入生成策略
      • 固定参数(边界值分析、等价类划分、测试用例设计)
      • 模糊测试(机器生成输入):libFuzzerAFL++
    • 运行时观测
      • 动态错误检测:ASan(内存错误)、UBSan(为定义行为)、TSan(线程竞争)、MSan(未初始化内存)
      • 覆盖率测试:gcov/lcovllvm-covOpenCppCoverage
      • 性能测试:Google Benchmark
    • 变异测试:Mull
  • 辅助工具
    • 依赖隔离:GoogleMock
  • 测试目标
    • 可靠性/稳定性
    • 性能
    • 安全
    • 兼容性
    • 回归

单元测试

对于单元测试,几乎适用所有的测试方法。

通常使用GoogleTest做单元测试框架。使用时,可以先进行边界值分析和等价类划分,从而确定一组全面的输入参数,或者使用libFuzzerAFL++进行模糊输入测试。

测试过程中,可以附加动态错误检测、覆盖率测试和性能测试等环节。

而整个测试流程中,为了确保测试是否足够强,可以附加变异测试。

对于被测试的单元,为了不受其他依赖的影响,可以使用GoogleMock来隔离其他依赖,只关注被测试单元。

集成测试

系统测试

验收测试(端到端测试)

此环节通常进行端到端测试,即对程序的全黑盒测试。模拟实际用户的行为对程序进行操作,并观察功能和性能是否符合预期。