如何正确处理 GCC 测试覆盖率分析的输出目录?
How do I correctly handle output directories for GCC test coverage profiling?
我正在尝试为我的单元测试生成覆盖率数据,最终目标是将所述数据显示为我们自动构建输出的一部分。
我们使用 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
其中 all
依赖于所有定义的单元测试可执行文件。
为了支持并行构建,我在 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
选项,但 none 似乎让这一切变得更好。
我是 运行 这个基于 Windows 10 的 Eclipse CDT - 这是我们的要求。根据其他答案,我怀疑可能存在路径 and/or 目录分隔符问题,但实际上我现在不确定任何事情。
我的问题是:我需要通过 makefile 进行哪些更改,以便我可以将此覆盖率数据添加到我们的构建中,从而继续支持并行构建?
我当然可以重组我们的单元测试以拥有一个 makefile-per-unit-test-suite,但这是大量的工作,我想尽可能避免它。
问题是 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
我正在尝试为我的单元测试生成覆盖率数据,最终目标是将所述数据显示为我们自动构建输出的一部分。
我们使用 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
其中 all
依赖于所有定义的单元测试可执行文件。
为了支持并行构建,我在 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
选项,但 none 似乎让这一切变得更好。
我是 运行 这个基于 Windows 10 的 Eclipse CDT - 这是我们的要求。根据其他答案,我怀疑可能存在路径 and/or 目录分隔符问题,但实际上我现在不确定任何事情。
我的问题是:我需要通过 makefile 进行哪些更改,以便我可以将此覆盖率数据添加到我们的构建中,从而继续支持并行构建?
我当然可以重组我们的单元测试以拥有一个 makefile-per-unit-test-suite,但这是大量的工作,我想尽可能避免它。
问题是 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