Как показано на рисунке, HelloController был отправлен в главную ветку, а затем из главной ветки был получен новый тест; был отправлен первый код, добавлен второй код и добавлен DonController; Получить прибавки можно двумя способами:
Приращение,То есть посредством сравнения версий или сравнения ветвей.,Дополнительная недавно добавленная часть кода. Покрытие относится к времени после запуска программы.,Сколько кода было выполнено,Рассчитывается путем деления общего количества кодов,Прямо сейчасПокрытие = количество строк исполняемого кода/общее количество строк кода.
。Приращение Покрытие рассчитано на Приращениекод для расчета,То естьПриращение Покрытие=Количество выполненных строк кода/Приращение Строки кода
。
Используйте режим JaCoCo «на лету», запустите его в режиме tcpserver, сбросьте данные о покрытии удаленного компьютера в локальный файл jacoco.exec через TCP-связь и вторично разработайте исходный код JaCoCo для реализации поэтапного анализа покрытия и вывода отчетов в формате HTML. .
JaCoCo — это инструмент покрытия с открытым исходным кодом. Его режим «на лету» не требует вмешательства в сценарий запуска приложения. Вам нужно только указать программу-агент, запускаемую файлом jar, через параметр -javaagent в программе-агенте. определяет до того, как ClassLoader загрузит класс, необходимо ли внедрить файл класса и вставить в класс статистический код, анализ покрытия может быть завершен во время выполнения JVM.
Пример сценария запуска:
java -javaagent:jacocoagent.jar -jar target/app.jar
По умолчанию,JaCoCo сгенерирует данные о покрытии после остановки JVM.,Файл jacoco.exec.
В официальном руководстве также есть соответствующие инструкции:
вывод по умолчанию в файл: At VM termination execution data is written to the file specified in the destfile
атрибут. Этот метод имеет два ограничения. Во-первых, приложение должно быть остановлено, во-вторых, данные о покрытии могут быть сгенерированы только в локальные файлы.
Есть еще один вариант вывода: tcpserver.:
java -javaagent:jacocoagent.jar=output=tcpserver,address=0.0.0.0,port=2014 -jar target/app.jar
адрес: адрес сервера;
порт: порт сервера;
После начала таким образом,Одновременно будет запущен TCP-сервер.,использоватьlsof -i :2014
Команда для просмотра процессов порта:
Затем вы можете общаться через TCP,чтобы получить данные о покрытии,То естьтак называемый”dump“。
Фрагмент кода:
@Override
public void dump(String dumpPath, String ip, int port) throws IOException {
dumpPath = FileUtil.getAbsolutePath(dumpPath);
if (!FileUtil.exist(dumpPath)) {
FileUtil.mkdir(dumpPath);
}
FileOutputStream localFile = new FileOutputStream(dumpPath + File.separator + "jacoco.exec");
ExecutionDataWriter localWriter = new ExecutionDataWriter(localFile);
SocketAddress socketAddress = new InetSocketAddress(ip, port);
Socket socket = new Socket();
try {
socket.connect(socketAddress, 10000);
RemoteControlWriter writer = new RemoteControlWriter(socket.getOutputStream());
RemoteControlReader reader = new RemoteControlReader(socket.getInputStream());
reader.setSessionInfoVisitor(localWriter);
reader.setExecutionDataVisitor(localWriter);
log.info("Начать дамп:{} {}", ip, port);
writer.visitDumpCommand(true, false);
if (!reader.read()) {
log.error("Socket closed unexpectedly");
throw new IOException("Socket closed unexpectedly.");
}
log.info("дамп завершен: {} {}", ip, port);
} catch (Exception e) {
log.info("Ошибка дампа: {}", e.getMessage());
} finally {
socket.close();
localFile.close();
}
}
После того, как дамп передает данные о покрытии удаленного компьютера на локальный через TCP-соединение, он создает файл jacoco.exec, а затем вы можете использовать jacococli.jar для создания отчета HTML:
java -jar jacococli.jar report ./dump/jacoco.exec --classfiles ./target/classes/ --sourcefiles ./src/main/java/ --html ./report
Первый параметр: путь к файлу jacoco.exec;
Второй параметр: путь к файлу класса;
Третий параметр: путь к исходному коду src;
Четвертый параметр: адрес хранения отчета;
JaCoCo также предоставляет OpenApi для создания отчетов.
Фрагмент кода:
dumpPath = FileUtil.getAbsolutePath(dumpPath);
classFilesPath = FileUtil.getAbsolutePath(classFilesPath);
srcPath = FileUtil.getAbsolutePath(srcPath);
reportPath = FileUtil.getAbsolutePath(reportPath);
File execFile = new File(dumpPath + File.separator + "jacoco.exec");
ExecFileLoader execFileLoader = new ExecFileLoader();
execFileLoader.load(execFile);
CoverageBuilder coverageBuilder = new CoverageBuilder();
Analyzer analyzer = new Analyzer(execFileLoader.getExecutionDataStore(), coverageBuilder);
analyzer.analyzeAll(new File(classFilesPath));
String reportTile = «Название отчета»;
IBundleCoverage bundleCoverage = coverageBuilder.getBundle(reportTile);
HTMLFormatter htmlFormatter = new HTMLFormatter();
IReportVisitor iReportVisitor = htmlFormatter.createVisitor(new FileMultiReportOutput(new File(reportPath)));
iReportVisitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(), execFileLoader.getExecutionDataStore().getContents());
DirectorySourceFileLocator directorySourceFileLocator = new DirectorySourceFileLocator(new File(srcPath), "utf-8", 4);
iReportVisitor.visitBundle(bundleCoverage, directorySourceFileLocator);
iReportVisitor.visitEnd();
Пакеты org.jacoco.core и org.jacoco.report компании JaCoCo предоставляют эти методы.
По умолчанию JaCoCo может анализировать только полное покрытие.
Основная логика преобразования заключается в том, что при анализе данных покрытия файл класса выбирает только файлы git diff, так что для достижения добавочного покрытия учитывается только добавочный код с различиями.
существоватьClassProbesAdapterсортvisitMethod
внутри метода,Имеется логика расчета зонда на уровне метода.,трансформировать его,Анализируются только новые или измененные методы каждого извлеченного класса.
Фрагмент кода:
CoverageBuilder.classInfos — это класс различий, полученный из git diff.
Измените CoverageBuilder для поддержки сравнения ветвей и версий:
Получите код разницы, используя jgit и jdt, чтобы сократить его до детализации метода:
Полный исходный код можно найти в проекте с открытым исходным кодом JacocoPlus:
https://github.com/512433465/JacocoPlus
Иногда результаты анализа покрытия JaCoCo бывают неточными, обычно это связано с этими двумя ключевыми моментами:
Первый — это дамп. Частота дампа очень важна. Рекомендуется делать дамп один раз при каждом анализе, чтобы гарантировать актуальность данных о покрытии. Распределенный кластер будет иметь несколько копий данных покрытия. Вы можете использовать методы загрузки и сохранения ExecFileLoader для объединения нескольких копий данных в одну. Перезапуск приложения приведет к потере данных о покрытии, поэтому вы можете сделать несколько резервных копий.
Второе — класс. При создании отчета класс и src будут сравниваться для расчета покрытия. Только когда класс и src полностью совпадают, мы можем получить точное покрытие, если сами вытащим последний код и скомпилируем его, чтобы получить класс, потому что из-за этого. из-за влияния среды и версии компиляции скомпилированный класс может не соответствовать src, и статистические результаты не будут точными. Лучше всего извлечь развернутый класс из приложения для сравнения, чтобы убедиться в полном совпадении класса и src.
JaCoCo - Java Agent https://www.jacoco.org/jacoco/trunk/doc/agent.html JaCoCo - API Usage Examples https://www.jacoco.org/jacoco/trunk/doc/api.html Инструмент добавочного покрытия кода https://tech.youzan.com/yzicov/ Точная практика тестирования Youzan https://tech.youzan.com/thanos/ Краткое изложение различных форм покрытия Java. Инструментарий Jacoco и записи ошибок. https://testerhome.com/topics/20632 jacoco Некоторые подводные камни, возникающие при использовании покрытия кода https://testerhome.com/topics/16925 jacoco — реализация поэтапного покрытия кода https://blog.csdn.net/qq_34811445/article/details/127556617