Unit testing 大型项目的gcov(静态库,…)

Unit testing 大型项目的gcov(静态库,…),unit-testing,gcc,build-process,code-coverage,gcov,Unit Testing,Gcc,Build Process,Code Coverage,Gcov,我正在进行一个较大的项目,该项目具有以下目录布局: Source MyA aa.cpp ab.cpp ac.cpp MyB ba.cpp bb.cpp bc.cpp MyTest testaa.cpp testab.cpp testac.cpp testba.cpp testbb.cpp testbc.cpp main.cpp Build MyA aa.o ab.o ac.o libMyA.a (static libra

我正在进行一个较大的项目,该项目具有以下目录布局:

Source
 MyA
  aa.cpp
  ab.cpp
  ac.cpp
 MyB
  ba.cpp
  bb.cpp
  bc.cpp
 MyTest
  testaa.cpp
  testab.cpp
  testac.cpp
  testba.cpp
  testbb.cpp
  testbc.cpp
  main.cpp
Build
 MyA
  aa.o
  ab.o
  ac.o
  libMyA.a (static library)
 MyB
  ba.o
  bb.o
  bc.o
  libMyB.a (static library)
 MyTest
  testaa.o
  testab.o
  testac.o
  testba.o
  testbb.o
  testbc.o
  MyTest (executable)
使用
-fprofile arcs-ftest coverage
编译后,我在Build/MyTest目录中执行MyTest应用程序。正如预期的那样,生成目录中有*.gcno和*.gcda文件。在MyTest目录中运行gcov之后,会生成不同的*.gcov文件,但不幸的是,并非MyA和MyB中的所有文件都会生成该文件,尽管这两个库中的每个函数都会被调用。尝试了不同的选项,但不知何故,我无法使用此布局创建有用的(正确的)*.gcov文件


如果我将每个cpp复制到一个目录中并重复这些步骤,那么一切都会按预期进行,覆盖率分析也会很完美。

为了能够保持目录结构,您需要在每个源文件文件夹中运行一次gcov,但使用
-o
选项告诉gcov数据文件在哪里

我认为应该是这样的:

gcov -o ../../Build/MyA *.cpp
gcov -o Source/MyA Source/MyA/aa.cpp
我有一个具有类似源文件结构的项目,但我让编译器将对象文件等转储到源文件夹中。然后,我从根文件夹多次运行gcov,每个源文件一次,但我指定源文件的相对路径,并使用
-o
选项指定相对文件夹,如下所示:

gcov -o ../../Build/MyA *.cpp
gcov -o Source/MyA Source/MyA/aa.cpp
  • 必须将源文件指定为g++/gcc的绝对路径。不要将相对路径与“.”或类似“foo/bar.cpp”一起使用,否则会出现类似“geninfo:警告:找不到XXXX的数据”这样的错误

  • 不要在g++/gcc的命令行中包含任何头文件。否则将出现“与图形文件不匹配的戳记”错误

  • 因此,当有多个目录时,以下内容应起作用:

    g++ --coverage -DDEBUG -g3 heyo.cpp /app/helper/blah.cpp /app/libfoo/foo.cpp -o program
    
    ./program
    
    lcov --directory . --capture --output-file app.info
    
    genhtml --output-directory cov_htmp app.info
    
    或者,如果您所在的Makefile已经使用了相对路径,则可以方便地使用:

    g++ --coverage -DDEBUG -g3 $(abspath heyo.cpp helper/blah.cpp ../foo/bar/baz.cpp) -o program
    

    如果您彻底地、手动地执行产品或应用程序测试,并为此付出了大量的努力。如果您的目标是使用lcov和gcov获得代码覆盖率报告,但错误地删除了gcno文件。您可以通过重新编译代码来重新生成gcno文件,但它将使用新的时间戳生成,并且gcov报告错误“与图形文件不匹配”,并且不会生成代码覆盖率报告。这将导致您所有的测试工作被浪费

    还有一个快捷方式可以生成代码覆盖率报告。这只是一种变通方法,不应该一直依赖它。建议在测试完成之前保留*.gcno文件

    记下您的gcc版本(gcc-v),并从镜像站点之一下载其源代码 例如

    解压缩下载的文件后,文件夹结构如下 gcc-4.4.6 gcc-4.4.6/gcc

    如果您直接进入gcc-4.4.6/gcc并尝试从那里执行/配置和编译(make),那么您将遇到以下问题 构建/生成模式-h>tmp模式.h /bin/sh:build/genmodes:没有这样的文件或目录

    解决方案是根据gcc-4.4.6进行do./configure和make,不会显示与genmodes相关的错误。这将编译包括gcc在内的所有模块。如果出现./configure显示的任何错误,您可能必须安装gcc所需的mpfr和gmp模块

    转到gcc-4.4.6/gcc/gcov.c并在下面的行中进行注释,然后使用上面的命令重新编译

    /*  if (tag != bbg_stamp)
        {
          fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
          goto cleanup;
        }*/
    
    编译后新gcov二进制文件的示例路径是gcc-4.4.6/host-x86_64-unknown-linux-gnu/gcc/gcov

    将此二进制文件放入/usr/bin中,并使用命令重新生成代码覆盖率报告,如下例所示 lcov——捕获——目录。/——输出文件coverage.info;genhtml coverage.info——输出目录/var/www/html/coverage


    现在,您不应该得到“stamp mismatch with graph file”错误,您将正确地得到代码覆盖率报告

    我假设您也从根目录调用gcc/g++?如果我只是在任何目录中使用-o选项,那么我的所有*.gov文件都包含大量/*EOF*/alt,尽管所有路径都设置正确。可能我的主要问题是生成系统(qmake)从不同的位置调用编译器。@azraiyl:我使用SCON来生成项目,所以我不完全确定,但是,是的,我认为SCON使用到源文件的相对路径。这在我的情况下非常有效。谢谢。我想我以前低估了lcov。有很多有用的信息,但没有回答最初的问题。