解释gcov输出以提高覆盖率的技巧是什么
What are your tips for interpreting gcov output in order to improve coverage?
我在我的项目中成功地使用了gcov:
- 我可以使用gcov标志构建我的项目:
-fprofile-arcs -ftest-coverage
- 我链接到
-lgcov
选项 - 我运行了我的单元测试程序,生成了许多
gcda
和gcno
文件 - 我运行了很多次gcov,生成了很多
gcov
文件 - 我总结了结果,并列出了如下行:
#####: 42: virtual double run_time() const { return 0; }
然后我说"doh!"并编写一个测试来调用丢失的方法。
上面的示例行很容易诊断——gcov告诉了我没有调用的确切方法。
我也有一个复制构造函数被gcov标记的例子,但我可以使用我的VisualStudio调试器逐步完成它。解决方案是意识到gcov患有RVO,RVO删除了副本,但编写了一个强制副本的测试修复了这一问题。
我还有几个其他的例子,我无法理解:
1.
File.cpp
#####: 78:}
gcov似乎在标记一个名称空间的右大括号,该名称空间是文件的最后一行。
2.
File.h
#####: 33: class FooBase: public IResult {
gcov在这里想告诉我什么?我想不出在这里打什么电话了
更新1:我已经检测到FooBase
有一个默认的构造函数,就gcov
而言,如果仅由子类"调用",则与通过实例化来调用它不同。
更新2:我一直在使用djgpp/gcc 4.4.4
,它产生了上述结果。然而,通过使用MinGW/gcc 4.5.2
,"像差"消失了,再做一点工作,我就可以达到100%的线路覆盖率。
请给粗心的gcov用户写一个提示,或者给我的一个例子写一个答案。
正如gcov.c 中所说
/* For lines which don't exist in the .bb file, print '-' before
the source line. For lines which exist but were never
executed, print '#####' before the source line. Otherwise,
print the execution count before the source line. There are
16 spaces of indentation added before the source line so that
tabs won't be messed up. */
我建议您在尝试获得覆盖率时使用gcov和VS的调试构建。
您所讨论的行将在发布模式下内联。这意味着行本身永远不会被计数(尽管坦率地说,计数器的增量可能已经被移动到函数内联的地方……但g++还没有做到这一点。)
为了解决这个问题,将-g
添加到g++命令行中以保持所有调试。您可能还需要确保定义了-D_DEBUG
。实际上,文档通常告诉您使用-g
。
最后,您希望避免使用-O0
进行优化。
就我而言,我也喜欢使用-fprofile-arcs
和-ftest-coverage
。
正如另一个答案中的注释所提到的,使用-fno-elide-constructors
和-fno-default-inline
也可能有助于覆盖"丢失"的构造函数和内联函数。
关于被标记的左大括号,g++可能会创建一个构造函数(可能是复制构造函数),并将其显示在第一个类声明行上。可能还有其他编译器特定的函数像这样创建,有时如果没有极其复杂的测试用例,就不可能实现它们。。。我总是遇到那个问题。
根据气候变化专家的建议,你可以使用lcov。这为您提供了HTML作为输出,其中包含易于阅读的表,您可以快速浏览这些表。我这里有这样一个例子:
http://lcov.csspp.org/csspp-1.0.5/lib/index.html
正如我们所看到的,所有测试都100%覆盖了库。但不知怎么的,assembly.cpp文件说有一个函数没有被覆盖。我不知道是哪个函数,因为我写的代码100%都涵盖了。。。所以我忽略了这一点。
最近我一直在使用cmake+"make Experimental"+lcov。我强烈推荐这种组合。即使不使用cmake,也可以看看lcov。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 与模板配合使用的最佳C++代码覆盖率工具是什么?
- 解释gcov输出以提高覆盖率的技巧是什么