代码覆盖率优化

Ziz*_*Tai 3 c++ unit-testing code-coverage

目前我有一堆针对我的 C++ 项目的单元测试,但我还没有(还)测试代码覆盖率。我正在使用-O3优化标志编译测试以暴露潜在的细微错误,但似乎如果我想使用诸如 之类的工具收集覆盖率信息,则gcov必须禁用任何优化标志。我应该构建两次测试(一个有-O3,另一个没有)?这个问题一般是怎么处理的?

Mat*_*son 5

通常会执行多种测试来确保软件的质量,以及针对哪些编译器选项的不同标准。

通常,构建系统提供两种或多种构建选择,例如:

调试:-O0(无优化)与断言

发布:“更高的优化”(-O2、-Os 或 -O3,取决于什么对您的项目来说是“最佳”的),没有断言。这通常是您将代码交付给客户的模式。

有时会有“Release+Asserts”,这样你仍然可以在运行时检查代码的正确性,并具有一些性能。

以下是我认为测试可以分为的一些类别:

  1. 功能正确性(又名“阳性测试”)。这是您检查“代码在正常情况下正常工作”的地方。运行调试和发布。

  2. 阴性测试。检查错误条件是否正常工作 - 传递应该给出错误的垃圾值(“不存在的文件”应该给出 E_NO_SUCH_FILE)。通常既调试又发布。

  3. 压力测试 - 运行苛刻的测试,以检查软件在长时间运行时是否正确运行,有很多线程等。通常是调试模式 - 可能两者兼而有之。

  4. 覆盖范围。运行一组测试以确保您“覆盖所有路径”(通常具有“未覆盖”的程度,例如您应该覆盖 95% 的功能和 85% 的分支——因为某些条件可能极难实现无需手动检测代码 - 只有在磁盘完全满时或操作系统无法创建新进程时才会出现错误)。通常编译为 Debug。

  5. 容错测试。一种“否定测试”形式,您可以为内存分配插入“模拟”功能和类似功能,依次或随机模拟失败,以发现未检测到错误并且代码失败作为后续结果的情况更早的错误,而不是在正确的地方产生正确的错误。同样,通常使用 Debug 运行 - 但也可能值得在 Release 中运行。

  6. 性能测试。您测量程序性能的地方 - 生成的每秒帧数、编译器中的每秒行数或文件下载系统中的每小时千兆字节等。这应该按照版本进行编译,因为在“未优化”代码中的运行性能是几乎总是毫无意义。

对于复杂的软件产品,你常常不得不在“运行一切”和“花费的时间”之间做出妥协——例如,在调试和发布模式下运行所有​​ 4000 个功能测试可能需要 12 小时,仅运行调试模式需要 7 小时,如此可取。这种妥协是通常的“工程决策”——“在理想的世界中,你会这样做,但在现实世界中,我们必须妥协,这就是为什么我认为这种测试配置是正确的”。

例如,许多测试系统对源代码的每次更改都进行轻量级测试(在工程师他/她自己“我认为这可行”之后),每晚进行更重的测试,周末进行更多测试。这允许在运行所有测试所需的时间和一名工程师进行小改动所需的时间之间进行折衷。