Как правильно обрабатывать выходные каталоги для профилирования покрытия теста 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

Другие вопросы по тегам