Gradle Jacoco и JUnit5
Мы просто портировали наши юнит-тесты на JUnit5. Понимая, что это все еще довольно раннее принятие с небольшими намеками на Google.
Самым сложным было получить покрытие кода jacoco для тестов Junit5, которые мы используем на jenkins. Поскольку это заняло у меня почти день, чтобы понять, я решил поделиться. Тем не менее, если вы знаете лучшее решение, мне было бы интересно узнать!
buildscript {
dependencies {
// dependency needed to run junit 5 tests
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-M2'
}
}
// include the jacoco plugin
plugins {
id 'jacoco'
}
dependencies {
testCompile "org.junit.jupiter:junit-jupiter-api:5.0.0-M2"
runtime "org.junit.jupiter:junit-jupiter-engine:5.0.0-M2"
runtime "org.junit.vintage:junit-vintage-engine:4.12.0-M2"
}
apply plugin: 'org.junit.platform.gradle.plugin'
Тогда проблема, по-видимому, заключается в том, что junitPlatformTest, как определено в org.junit.platform.gradle.plugin, определен слишком поздно на этапе жизненного цикла gradle и, следовательно, неизвестен при синтаксическом анализе сценария.
Следующий хак нужен для того, чтобы все еще иметь возможность определить задачу jacoco, которая наблюдает за задачей junitPlatformTest.
tasks.whenTaskAdded { task ->
if (task.name.equals('junitPlatformTest')) {
System.out.println("ADDING TASK " + task.getName() + " to the project!")
// configure jacoco to analyze the junitPlatformTest task
jacoco {
// this tool version is compatible with
toolVersion = "0.7.6.201602180812"
applyTo task
}
// create junit platform jacoco task
project.task(type: JacocoReport, "junitPlatformJacocoReport",
{
sourceDirectories = files("./src/main")
classDirectories = files("$buildDir/classes/main")
executionData task
})
}
}
Наконец, необходимо настроить плагин junitPlatform. Следующий код разрешает настройку командной строки, из которой должны запускаться теги junit 5: Вы можете запустить все тесты с тегом "unit", выполнив:
gradle clean junitPlatformTest -PincludeTags=unit
Вы можете запустить все тесты, в которых отсутствует как единичный тег, так и тег целых
gradle clean junitPlatformTest -PexcludeTags=unit,integ
Если теги не указаны, будут запущены все тесты (по умолчанию).
junitPlatform {
engines {
include 'junit-jupiter'
include 'junit-vintage'
}
reportsDir = file("$buildDir/test-results")
tags {
if (project.hasProperty('includeTags')) {
for (String t : includeTags.split(',')) {
include t
}
}
if (project.hasProperty('excludeTags')) {
for (String t : excludeTags.split(',')) {
exclude t
}
}
}
enableStandardTestTask false
}
4 ответа
Спасибо, так что хак теперь выглядит так:
project.afterEvaluate {
def junitPlatformTestTask = project.tasks.getByName('junitPlatformTest')
// configure jacoco to analyze the junitPlatformTest task
jacoco {
// this tool version is compatible with
toolVersion = "0.7.6.201602180812"
applyTo junitPlatformTestTask
}
// create junit platform jacoco task
project.task(type: JacocoReport, "junitPlatformJacocoReport",
{
sourceDirectories = files("./src/main")
classDirectories = files("$buildDir/classes/main")
executionData junitPlatformTestTask
})
}
Можно также решить с помощью прямой инъекции агента:
subprojects {
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.7.9"
}
configurations {
testAgent {
transitive = false
}
}
dependencies {
testAgent("org.jacoco:org.jacoco.agent:0.7.9:runtime")
}
tasks.withType(JavaExec) {
if (it.name == 'junitPlatformTest') {
doFirst {
jvmArgs "-javaagent:${configurations.testAgent.singleFile}=destfile=${project.buildDir.name}/jacoco/test.exec"
}
}
}
}
тогда отчет будет доступен с jacocoTestReport
задача
Чтобы получить ссылку на junitPlatformTest
задача, другой вариант заключается в реализации afterEvaluate
блок в проекте так:
afterEvaluate {
def junitPlatformTestTask = tasks.getByName('junitPlatformTest')
// do something with the junitPlatformTestTask
}
Смотрите мои комментарии на GitHub для JUnit 5 для дальнейших примеров.
Вам просто нужно добавить @RunWith(JUnitPlatform.class) в ваш пакет
@RunWith(JUnitPlatform.class)
public class ClassTest {
}