2016-09-07 4 views
17

Wir haben unsere Komponententests nur auf JUnit5 portiert. Realisierend, dass dies noch ziemlich früh mit kleinen Hinweisen auf Google Adoption ist.Gradle Jacoco und JUnit5

Die größte Herausforderung bestand darin, die jacoco-Codeabdeckung für die Junit5-Tests zu erhalten, die wir für jenkins verwenden. Da ich fast einen Tag brauchte, um es herauszufinden, dachte ich, ich teile es. Wenn Sie jedoch eine bessere Lösung kennen, würde mich das interessieren!

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' 

Dann scheint das Problem zu sein, dass junitPlatformTest wie im org.junit.platform.gradle.plugin definiert zu spät in der gradle Phase des Lebenszyklus definiert ist, und daher ist nicht bekannt, wann das Skript analysiert wird.

Der folgende Hack wird benötigt, um weiterhin eine jacoco-Task definieren zu können, die die Aufgabe junitPlatformTest beobachtet.

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 
      }) 
    } 
} 

Schließlich ist es notwendig, das junitPlatform Plugin zu konfigurieren. Der folgende Code ermöglicht Befehlszeilenkonfiguration von denen JUnit 5-Tags ausgeführt werden: Sie können alle Tests mit ‚Einheit‘ Tag laufen, indem Sie:

gradle clean junitPlatformTest -PincludeTags=unit 

Sie können alle Tests durchgeführt, die sowohl Einheit fehlen und integ-Tag mit

gradle clean junitPlatformTest -PexcludeTags=unit,integ 

Wenn keine Tags bereitgestellt werden, werden alle Tests ausgeführt (Standard).

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 
} 
+0

Ich stimme diese Frage als off-topic zu schließen, weil es eher Lösung als eine Frage ist – Stanislav

+1

Es wäre schön, wenn dies in eine Frage und eine Antwort getrennt wäre. –

+0

Ich stimme @PaulHicks zu, dass dies eine selbst beantwortete Frage sein sollte. Sie können die Dokumentation [hier] (https://stackoverflow.com/help/self-answer) sehen. Außerdem sollte das Problem "Zu spät im Gradle-Lebenszyklus" [in M5] behoben sein (https://github.com/junit-team/junit5/issues/708). – mkobit

Antwort

1

Um einen Verweis auf die junitPlatformTest Aufgabe zu bekommen, eine weitere Option ist ein afterEvaluate Block in das Projekt wie folgt umzusetzen:

meine Kommentare
afterEvaluate { 
    def junitPlatformTestTask = tasks.getByName('junitPlatformTest') 

    // do something with the junitPlatformTestTask 
} 

Siehe auf GitHub for JUnit 5 für weitere Beispiele.

5

Vielen Dank, so jetzt der Hack wie folgt aussieht:

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 
      }) 
} 
3

Kann auch mit direkter Mittelinjektion gelöst werden:

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" 
      } 
     } 
    } 
} 

dann berichten zur Verfügung stehen mit jacocoTestReport Aufgabe

+0

Danke Ian. Es funktioniert für mich – Sean

-2

Sie müssen nur @RunWith (JUnitPlatform.class) zu Ihrem Paket hinzufügen

@RunWith(JUnitPlatform.class) 
public class ClassTest { 
} 
Verwandte Themen