如何告诉gcov忽略C ++代码的不可击中的行?
我使用gcov来测量我的C ++代码的覆盖范围。 我想达到100%的覆盖率,但受到这样一个事实的阻碍:理论上有一些代码行是不可触发的(这些方法需要被实现但是从来没有被调用过,默认的switch
语句分支,等等。)。 每个分支都包含一个assert( false );
声明,但gcov仍然标志着他们未受打击。
我希望能够告诉gcov忽略这些分支。 有没有办法给gcov这些信息 – 通过注释的源代码,或通过任何其他机制?
请使用lcov。 它隐藏了gcov的复杂性,产生了很好的输出,允许每个testing的详细输出,具有简单的文件过滤function,以及用于已经复查的行的标记 – 行标记:
从geninfo(1):
以下标记由geninfo识别:
- LCOV_EXCL_LINE
- 包含这个标记的行将被排除。
- LCOV_EXCL_START
- 标记排除的部分的开始。 当前行是本节的一部分。
- LCOV_EXCL_STOP
- 标记排除部分的结尾。 当前行不是本节的一部分。
你能介绍一下相关函数的unit testing吗?这些unit testing是直接攻击理论上不可用的代码path而closures的。 既然他们是unit testing,他们也许可以忽略情况的“不可能”。 他们可以调用从不调用的函数,传递无效的枚举值来捕获默认分支等。
然后,或者只在你用NDEBUG编译的代码版本上运行这些testing,或者在一个testingassert被触发的线束中运行它们 – 不pipe你的testing框架支持什么。
我觉得这有点奇怪,但规范说,代码必须在那里,而不是包含代码function要求的规范。 尤其是,这意味着您的testing不会testing这些需求,这与保持需求的function一样是一个很好的理由。 就个人而言,我想修改规范说:“如果用一个无效的枚举值调用,函数将失败一个assert
。在释放模式下,调用者不应该调用具有无效枚举值的函数”。 还是一些这样的。
据推测,它目前所说的是,“所有开关语句必须有一个默认情况”。 但是这意味着编码标准通过引入死代码来干扰可观察到的行为(至less在gcov下可观察到)。 编码标准不应该这样做,所以如果可能的话,function规范应该考虑编码标准。
如果不这样做,你也许可以在#if !GCOV_BUILD
包装#if !GCOV_BUILD
用的代码,并为gcov的好处做一个单独的构build。 这个构build将会失败一些要求,但是在你对代码分析正确的条件下,它会给你一个信心,让你testing套件能够testing其他的一切。
编辑:你说你正在使用一个狡猾的代码生成器,但你也通过注释的源代码要求解决scheme。 如果你正在改变源代码,你能在很多情况下删除死代码吗? 不是改变生成的来源是理想的,但需要必须…
我不相信这是可能的。 Gcov依靠gcc生成额外的代码来产生覆盖率输出。 GCov本身只是parsing数据。 这意味着Gcov不能分析比gcc更好的代码(我假设你使用了-Wall,并且删除了被报告为不可访问的代码)。
请记住,可以从任何地方调用可重定位函数,甚至可能是外部dll或可执行文件,因此编译器无法知道哪些可重定位函数不会被调用或者这些函数可能具有哪些input。
您可能需要使用一些简单的静态分析工具来获取所需的信息。