为了通过启动一个小型C++测试项目来了解更多有关自动化测试的知识,我遇到了以下问题--尽管我的所有实际代码行和所有执行分支都被测试覆盖了,但lcov仍然将两行报告为未测试(它们只包含函数定义),以及一个“重复”构造函数方法,即使它与我的“真实”构造函数(唯一定义和使用的构造函数)完全匹配,也应该是未经测试的。
(跳过以编辑最小复制情况)
如果我使用gcovr脚本生成相同的覆盖率统计数据(来自相同的确切来源,.gcno和.gcda文件),并将结果传递给Jenkins Cobertura插件,那么它将给我100%的所有计数--行、条件和方法。
我的意思是:
Jenkins覆盖页面:cobertura.html (一切都在100%)。
使用lcov:lcov.html处理的相同的.gcda文件(标记为未执行的两个函数定义行,即使这些函数中的行已经完全覆盖,以及函数Hit =FunctionsTotal-1)。
来自lcov: http:// gints.dyndns.info/heap_lcov_func的源文件的函数统计数据(显示两个相同的构造函数定义,它们都引用文件中相同的代码行,其中一个标记命中5次,另一次标记为0次)。
如果我查看中间的lcov .info文件:filtered.info.txt,我会发现那里也有两个构造函数定义,它们都应该位于同一行: FN:8,_ZN4BBOS8Heap_stdC1Ev & FN:8,_ZN4BBOS8Heap_stdC2Ev。
哦,不要介意.uic包含/析构函数的杂乱无章,这只是一种处理What is the branch in the destructor reported by gcov?的肮脏方法--我在拍摄这些文件快照时碰巧尝试了一下。
有人对如何解决这个问题有建议吗?C++编译器在这里有什么“幕后”的魔力吗?(为了特殊目的,我应该确保从测试中调用构造函数的额外副本?)那么常规的函数定义呢?即使身体已经做了充分的测试,如何才能对定义行进行未经测试呢?这仅仅是lcov的问题吗?任何建议,欢迎-我想了解为什么会发生这种情况,如果真的有一些功能,我的测试是没有发现和Cobertura没有抱怨.否则,我如何让lcov明白这一点?
编辑:在下面添加最小的复制场景
lcov_repro_one_bad.cpp:
#include <stdexcept>
class Parent {
public:
Parent() throw() { }
virtual void * Do_stuff(const unsigned m) throw(std::runtime_error) =0;
};
class Child : public Parent {
public:
Child() throw();
virtual void * Do_stuff(const unsigned m)
throw(std::runtime_error);
};
Child::Child()
throw()
: Parent()
{
}
void * Child::Do_stuff(const unsigned m)
throw(std::runtime_error)
{
const int a = m;
if ( a > 10 ) {
throw std::runtime_error("oops!");
}
return NULL;
}
int main()
{
Child c;
c.Do_stuff(5);
try {
c.Do_stuff(11);
}
catch ( const std::runtime_error & ) { }
return 0;
}
makefile:
GPP_FLAGS:=-fprofile-arcs -ftest-coverage -pedantic -pedantic-errors -W -Wall -Wextra -Werror -g -O0
all:
g++ ${GPP_FLAGS} lcov_repro_one_bad.cpp -o lcov_repro_one_bad
./lcov_repro_one_bad
lcov --capture --directory ${PWD} --output-file lcov_coverage_all.info --base-directory ${PWD}
lcov --output-file lcov_coverage_filtered.info --extract lcov_coverage_all.info ${PWD}/*.*
genhtml --output-directory lcov_coverage_html lcov_coverage_filtered.info --demangle-cpp --sort --legend --highlight
下面是我从其中得到的报道:bad.cpp.gcov.html
正如您所看到的,所谓的不命中行是函数可能抛出的异常的定义,而函数列表中仍然存在额外的未命中构造函数(单击顶部的函数)。
我尝试从函数定义中删除抛出声明,这将处理函数声明:v1.cpp.gcov.html (如您所见,额外的构造函数仍然存在)中未执行的行。
我尝试将函数定义移到类体中,而不是稍后定义它们,这就去掉了额外的构造函数:v2.cpp.gcov.html (不过,您可以看到,Do_stuff函数定义仍然有一些奇怪之处)。
当然,如果我同时做上述两件事,一切都很好:ok.cpp.gcov.html
但我还是很困惑到底是什么原因造成的.而且我仍然希望将我的方法(包括构造函数)定义在一个单独的.cpp文件中,而不是在类体中,而且我确实希望我的函数具有它们可以抛出的定义良好的异常!
这是源代码,以防您想玩这个:src.zip
有什么想法吗?
谢谢!
发布于 2012-10-11 11:20:01
好的,在浏览了一些C++异常声明之后,我想我理解了发生了什么:
https://stackoverflow.com/questions/12807512
复制相似问题