1

我正在尝试为我的单元测试生成覆盖率数据,最终目标是将所述数据显示为我们自动构建输出的一部分。

我们使用 makefile 和cs-make,cxxtest作为单元测试框架进行构建。自动生成的测试运行程序文件是 C++,我们所有的应用程序文件都是 C。

单元测试可执行文件的单元测试目标和配方是:

.SECONDEXPANSION:
UnitTest/%.exe: UnitTest/Tests/$$*/$$*Tests_cxx.cpp
    cs-rm *.gcda
    ..\cxxtest\bin\cxxtestgen --error-printer -o $@ $(addsuffix .h, $(basename $@))
    gcc -ftest-coverage -fprofile-arcs $(INCLUDES) $($*_SOURCES) -o $@
    ./$@
    gcovr -v

$(INCLUDES)酌情使用$(SOURCES)

配方通过运行来执行(例如)

cs-make cs-make -C TestPlatform -f UnitTest\makefile UnitTest\Test1.exe

这将构建Test1.exe并生成.gcno文件。Test1.exe运行并生成.gcda文件。gcovr正确解释这些文件并输出覆盖数据。

到目前为止,一切都很好。但我们实际上是通过执行以下命令并行构建和运行多个单元测试:

cs-make -C TestPlatform -j -f UnitTest\makefile UnitTest\all

whereall取决于所有已定义的单元测试可执行文件。

为了支持并行构建,我在 GCC 调用中添加了这个选项:

-fprofile-dir=UnitTest/Tests/$*/Coverage

它将每个可执行文件的 .gcda 文件放在单独的目录中。

但是现在,gcovr 无法正确处理文件:

gcovr -v
Filters for --root: (1)
- <_sre.SRE_Pattern object at 0x0000000004FED600>
Filters for --filter: (1)
- DirectoryPrefixFilter(C\:\/Workspace\/CoverageTest\/TestPlatform\/)
Filters for --exclude: (0)
Filters for --gcov-filter: (1)
- AlwaysMatchFilter()
Filters for --gcov-exclude: (0)
Filters for --exclude-directories: (0)
Scanning directory . for gcda/gcno files...
Found 6 files (and will process 4)
Pool started with 1 threads
Processing file: C:\Workspace\CoverageTest\TestPlatform\UnitTest\Tests\Test1\Coverage\coverage.gcda
Running gcov: 'gcov C:\Workspace\CoverageTest\TestPlatform\UnitTest\Tests\Test1\Coverage\coverage.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory C:\Workspace\CoverageTest\TestPlatform\UnitTest\Tests\Test1\Coverage' in 'c:\users\jfowkes\appdata\local\temp\tmpdfjja7'
Processing file: C:\Workspace\CoverageTest\TestPlatform\Test1Tests_cxx.gcda
Running gcov: 'gcov C:\Workspace\CoverageTest\TestPlatform\Test1Tests_cxx.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory C:\Workspace\CoverageTest\TestPlatform' in 'c:\users\jfowkes\appdata\local\temp\tmpdfjja7'
Processing file: C:\Workspace\CoverageTest\TestPlatform\coverage.gcda
Running gcov: 'gcov C:\Workspace\CoverageTest\TestPlatform\coverage.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory C:\Workspace\CoverageTest\TestPlatform' in 'c:\users\jfowkes\appdata\local\temp\tmpdfjja7'
Processing file: C:\Workspace\CoverageTest\TestPlatform\UnitTest\Tests\Test1\Coverage\Test1Tests_cxx.gcda
Running gcov: 'gcov C:\Workspace\CoverageTest\TestPlatform\UnitTest\Tests\Test1\Coverage\Test1Tests_cxx.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory C:\Workspace\CoverageTest\TestPlatform\UnitTest\Tests\Test1\Coverage' in 'c:\users\jfowkes\appdata\local\temp\tmpdfjja7'
Gathered coveraged data for 0 files
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL                                          0       0    --%
------------------------------------------------------------------------------
cs-make: Leaving directory `C:/Workspace/CoverageTest/TestPlatform'

gcovr似乎正在查找文件并将它们交给gcov,但没有覆盖数据出现。

我尝试了各种不同的gcovr选择,但似乎没有一个能让这变得更好。

我在 Eclipse CDT 中的 Windows 10 上运行此构建 - 这是我们的要求。我根据其他答案怀疑可能存在路径和/或目录分隔符问题,但实际上我目前不确定。

我的问题是:我需要通过 makefile 进行哪些更改,以便我可以将此覆盖数据添加到我们的构建中,从而继续支持并行构建?

我当然可以重组我们的单元测试,使其拥有一个 makefile-per-unit-test-suite,但这是一项艰巨的工作,如果可能的话,我想避免它。

4

1 回答 1

2

问题是 gcovr/gcov 需要将覆盖率数据与源文件关联起来才能生成覆盖率报告,而使用-fprofile-dir使这变得困难。AFAIK gcovr 目前无法正确处理这种情况。在这种情况下, Gcovr 的--object-directory选项无法提供帮助。

考虑cd进入执行构建的临时目录。粗略地说,从

gcc --coverage test/source.c -o testfoo
./testfoo
gcovr

[[ -d build-foo ]] || mkdir build-foo
cd build-foo && gcc --coverage ../test/source.c -o testfoo
cd build-foo && ./testfoo
cd build-foo && gcovr -r ../test

不幸的是,这将是您的“每个测试套件生成文件”方法的变体。

另一种选择可能是在其他目录中并行运行测试,然后一次将一个测试套件的覆盖率数据复制回您的构建目录。这要求您为 GCOV_PREFIX 环境变量提供适当的路径。这与在交叉编译环境中使用 gcovr 的过程相同,正如 gocarlos 在 gcovr 问题跟踪器上所解释的那样:https ://github.com/gcovr/gcovr/issues/259#issuecomment-406788661

于 2018-10-24T14:11:18.283 回答