Categories: Разработка

c-code-coverage/

Определение степени покрытия кода тестами — это очень-очень важно как минимум по двум причинам. Во-первых, с его помощью вы проверяете, что тесты выполняют каждую из написанных вами строк кода хотя бы один раз. Если это не так, скорее всего, у вас довольно фиговые тесты. Во-вторых, вы можете найти «мертвый» код, который на самом деле никогда не выполняется, и выкинуть его. Сегодня мы выясним, как посмотреть code coverage в программах, написанных на языке C или C++.

Примечание: Аналогичные инструкции для Python вы найдете в заметке Памятка по написанию тестов при помощи PyTest , а для Scala — в заметке Тестирование в Scala с помощью ScalaTest и определение степени покрытия кода тестами .

Если вы используете GCC

Этот вариант был проверен мной на FreeBSD 10.3 и GCC 4.9. Дополнительно нам понадобится пакет lcov:

sudo pkg install lcov

При сборке проекта используем следующие флаги:

CFLAGS = «-fprofile-arcs -ftest-coverage»
LDFLAGS = «-lgcov»

Собираем проект, как обычно, затем выполняем make check . Выполняться он будет заметно медленнее, чем обычно. При этом будет сгенерирована куча *.gcda файлов:

find . / -type f -iname ‘*.gcda’

Агрегируем данные:

# во FreeBSD lcov иначе на найдет gcov
sudo ln -s / usr / local / bin / gcov49 / usr / local / bin / gcov

lcov —directory src —capture —output-file postgresql.info

Генерируем HTML-отчет:

mkdir .. / cov-report
genhtml -o .. / cov-report / postgresql.info

В конце выполнения программы увидим примерно такой самори:

Writing directory view page.
Overall coverage rate:
lines……: 63.2% (179603 of 284239 lines)
functions..: 69.5% (10550 of 15183 functions)

Его можно, например, парсить регулярными выражениями и в Jenkins считать билд сломанным, если процент покрытия кода тестами падает ниже заданного. Мы так пробовали делать, чтобы программисты не ленились писать тесты на новые фичи. Проверено, работает.

Так примерно выглядит сам отчет:

По отчету видно, какие куски кода не были выполнены:

Все просто и понятно!

Если вы используете CLang

Под FreeBSD построить отчет о покрытии кода при помощи CLang 3.8 у меня не получилось. При компиляции вылетает ошибка:

libclang_rt.profile-x86_64.a: No such file: No such file or directory

Похоже, что это косяк в LLVM 3.8, так как его компонент compiler-rt не собирается на FreeBSD .

В итоге мне пришлось воспользоваться Ubuntu 14.04 (я пока не спешу переходить на 16.04). Для установки CLang и LLDB 3.8 говорим:

wget http: // llvm.org / apt / llvm-snapshot.gpg.key -O |
sudo apt-key add

В /etc/apt/sources.list дописываем:

deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.8 main

Далее:

sudo apt-get update
sudo apt-get install clang- 3.8 lldb- 3.8 lcov

Проект собираем с теми же флагами, что использовали в случае с GCC:

CFLAGS = «-fprofile-arcs -ftest-coverage»
LDFLAGS = «-lgcov»

Опять-таки, говорим make check . Данные о покрытии кода собираются намного быстрее, чем в случае с GCC.

Теперь нам понадобится примерно такой скрипт /usr/bin/llvm-cov-wrapper:

#!/usr/bin/env perl

use strict ;
use warnings ;

my $args = «@ARGV» ;
print STDERR «LLVM-COV-WRAPPER: args = ‘$args’ n » ;

if ( $args eq «-v» ) {
print «gcov (FreeBSD Ports Collection) 4.2.4 20151202 » .
«(prerelease) n » ;
} else {
my $cmd = «llvm-cov-3.8 gcov $args» ;
print STDERR «LLVM-COV-WRAPPER: executing ‘$cmd’ n » ;
system ( $cmd ) ;
}

Агрегируем данные:

lcov —gcov-tool / usr / bin / llvm-cov-wrapper —directory .
—capture —output-file postgresql.info

Генерируем HTML-отчет:

mkdir .. / cov-report
genhtml -o .. / cov-report / postgresql.info

Зачем нужен этот уродливый хак с --gcov-tool ? Дело в том, что по умолчанию lcov использует утилиту gcov. В системе установлен gcov 4.8. Однако CLang генерирует *.gcda , совместимые с версией 4.2, и поэтому gcov не может их пропарсить. Передавая кастомный --gcov-tool мы (1) выводим фальшивый номер версии, заставляя lcov думать, что он использует gcov 4.2 (2) вместо gcov заставляем lcov использовать команду llvm-cov, кторая прекрасно парсит сгенерированные *.gcda файлы.

Заключение

Заметьте, что во многих проектах из описанного выше делать нужно далеко не все. В частности, в PostgreSQL можно получить отчет о покрытии кода тестами таким образом:

. / configure —enable-coverage # … а также прочие флаги
make && make check && make coverage
find . / -type f -iname ‘*.info’ | xargs genhtml -o .. / cov-report /

Ссылки по теме:

А строите ли вы отчеты о покрытии кода тестами и если да, то чем?

Дополнение: Вас также могут заинтересовать статьи Тестирование кода на C++ с помощью Google Test и Практика написания модульных тестов в языке Go .

admin

Share
Published by
admin

Recent Posts

Консоль удаленного рабочего стола(rdp console)

Клиент удаленного рабочего стола (rdp) предоставляет нам возможность войти на сервер терминалов через консоль. Что…

1 месяц ago

Настройка сети в VMware Workstation

В VMware Workstation есть несколько способов настройки сети гостевой машины: 1) Bridged networking 2) Network…

1 месяц ago

Логи брандмауэра Windows

Встроенный брандмауэр Windows может не только остановить нежелательный трафик на вашем пороге, но и может…

1 месяц ago

Правильный способ отключения IPv6

Вопреки распространенному мнению, отключить IPv6 в Windows Vista и Server 2008 это не просто снять…

1 месяц ago

Ключи реестра Windows, отвечающие за параметры экранной заставки

Параметры экранной заставки для текущего пользователя можно править из системного реестра, для чего: Запустите редактор…

1 месяц ago

Как управлять журналами событий из командной строки

В этой статье расскажу про возможность просмотра журналов событий из командной строки. Эти возможности можно…

1 месяц ago