Как правильно обрабатывать выходные каталоги для профилирования покрытия теста GCC?
Я пытаюсь сгенерировать данные покрытия для моих модульных тестов с конечной целью отображения этих данных как части нашего автоматизированного вывода сборки.
Мы строим с использованием make-файлов и 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
варианты, но ни один, кажется, не делает это лучше.
Я запускаю эту сборку на Windows 10 в Eclipse CDT - это требование для нас. Основываясь на других ответах, я подозреваю, что могут быть проблемы с путями и / или разделителями каталогов, но на самом деле я пока не уверен ни в чем.
Мой вопрос: какие изменения мне нужно внести в make-файл, чтобы я мог добавить эти данные покрытия в нашу сборку, которая продолжает поддерживать параллельные сборки?
Конечно, я могу реструктурировать наше модульное тестирование так, чтобы в нем был пакет makefile-per-unit-test-suite, но это существенная работа, и я хотел бы избежать ее, если это вообще возможно.
1 ответ
Проблема заключается в том, что 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
К сожалению, это будет вариант вашего подхода "Makefile per test suite".
Другой альтернативой может быть параллельное выполнение тестов в других каталогах, а затем копирование данных покрытия по одному набору тестов за раз обратно в каталог сборки. Для этого необходимо указать соответствующие пути для переменной среды GCOV_PREFIX. Это будет та же процедура, что и для использования gcovr в среде кросс-компиляции, как объяснил gocarlos на трекере проблем gcovr: https://github.com/gcovr/gcovr/issues/259