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

优化的代码覆盖率 目前我有一个单元测试用于我的C++项目,但是我还没有测试代码覆盖率。我正在使用-O3优化标志编译测试,以暴露潜在的细微缺陷,但如果我想使用gcov之类的工具收集覆盖率信息,则必须禁用任何优化标志。我是否应该构建两次测试(一个有-O3,另一个没有)?这个问题通常是如何处理的?,c++,unit-testing,code-coverage,C++,Unit Testing,Code Coverage,为了确保软件的质量,通常要执行多种测试,对于哪些编译器选项有不同的标准 通常,生成系统提供两个或多个生成选项,例如: 调试:-O0(无优化)和断言 发布:“更高的优化”(-O2、-Os或-O3,取决于对项目“最佳”的内容),无需断言。这通常是您向客户交付代码的模式 有时会有“Release+Asserts”,这样您仍然可以在运行代码时检查代码的正确性,同时表现出一定的性能 我认为测试可以分为以下几类: 功能正确性(也称为“阳性测试”)。这是您检查“代码在正常情况下正常工作”的地方。运行调试和发布

为了确保软件的质量,通常要执行多种测试,对于哪些编译器选项有不同的标准

通常,生成系统提供两个或多个生成选项,例如:

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

发布:“更高的优化”(-O2、-Os或-O3,取决于对项目“最佳”的内容),无需断言。这通常是您向客户交付代码的模式

有时会有“Release+Asserts”,这样您仍然可以在运行代码时检查代码的正确性,同时表现出一定的性能

我认为测试可以分为以下几类:

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

  • 阴性测试。检查错误条件是否正常工作-传递应该给出错误的垃圾值(“不存在的文件”应该给出E_NO_这样的文件)。典型的是调试和发布

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

  • 覆盖范围。运行一组测试以确保“覆盖所有路径”(通常具有“未覆盖”的程度),例如,您应该涵盖95%的函数和85%的分支-因为如果不手动检测代码,可能很难实现某些条件-只有当磁盘已满或操作系统无法创建新进程时才会发生错误)。通常编译为调试

  • 容错测试。一种形式的“负面测试”,其中为内存分配和类似操作插入“模拟”功能,模拟顺序或随机出现的故障,以发现未检测到错误且代码因早期错误而失败的情况,而不是在正确的位置产生正确的错误。同样,通常使用Debug运行,但也值得在发行版中运行

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

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


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

    这个问题通常如何处理?
    我正在使用
    -O0
    编译测试。使用Valgrind(或gcc的一些
    sanitize
    标志)等探查器更适合查找潜在的bug<代码>-O3适用于性能基准测试。@GLUTTON是的,我正在使用Valgrind运行测试。
    -O0
    是否与无优化标志相同?因为它是默认选项。
    是否-O0与无优化标志相同?
    是的。正如您在第4节中所说,
    -O0
    应用于覆盖率测试。是吗?是的,经常是这样,但不总是这样。特别是如果您有调用函数检查内容的
    #if DEBUG
    ,关闭DEBUG将给出不同的覆盖结果。另一方面,取决于覆盖工具的性能[它与编译器的交互程度],它可能无法“看到”来自内联函数的覆盖,因此完全优化的覆盖也可能无法很好地工作。这其中的一部分取决于您正试图使用覆盖率工具实现什么—测试代码的生产版本,或者检查测试是否覆盖所有分支,等等。。。