Jacoco Unit-und Integration Tests, coverage - individuellen und Allgemeinen
Habe ich ein Projekt (ProjectA), die enthält einige unit-tests und integration-tests.
Folgenden ist die Struktur.
ProjectA
- src/java (java-Quellcode)
- test/java (Junit unit-tests)
- test/resources (Ressourcen für die Junit-Unit tests)
- src/java-test (Integration tests)
- conf (enthält .xml-Dateien, die erforderlich sind für den Aufbau/testen/kompilieren Zwecke)
Ich die folgenden Befehle ausführen -- Alle von Ihnen funktioniert, aber ich habe Zweifel, wie die Konfigurationen, die ich in build.gradle /GRADLE_HOME/init.d/*.gradle-Dateien betroffen sind, was ich bekomme.
Wie es scheint, bin ich etwas fehlt und nicht immer wo ich was haben möchte.
Befehle:
- gradle clean build -- es funktioniert gut
- gradle clean build jacocoTestReport-es funktioniert einwandfrei.
- gradle clean build integrationTest jacocoTestReport -- es funktioniert gut (wenn ich eine tomcat-Instanz implementiert und läuft in einem anderen putty-Fenster für die gleiche ProjectA).
Nach der 3. Kugel-Vorgang abgeschlossen ist, sehe ich den extra-Ordner "build" und dessen Unterordner (andere als das, was aus überprüft source/version control) in meinem Jenkins-jobs-Arbeitsbereich.
d.h. unter -- JenkinsWorkspace
/bauen
- Klassen (enthält .die class-Dateien für die folgenden genannt werden als einer der sourceSets Abschnitt)
---- integrationTest
---- main
- - - - - test
- Ressourcen (diese enthält alle Dateien .properties/.xml Dateien, die unter "conf" - Ordner im source control.
- Berichte (enthält .xml/.html Dateien für PMD/CheckStyle/Findbugs und Testergebnisse für entweder Einheit oder ES Tests, aber NICHT beide).
---- checkstyle
---- findbugs
---- pmd
---- jacoco
- - - - - tests (Hinweis: das ist plural, d.h. es ist kein "test", die definiert ist als ein Eintrag in sourceSets)
- jacoco (Diese enthält 2 .exec-Dateien, also testen.exec-und integrationTest.exec-beide haben unterschiedliche Datei-Größe)
- - - - - test.exec
---- integrationTest.exec
- jacocoHtml (Dieser Ordner enthält viele Ordner (mit .html-Dateien) und vor allem "index.html" unter ihm.
---- somexxxfolders
---- ---- somexxfolder's.html Dateien
---- index.html
---- andere etc Dateien/Ordnern
- test-Ergebnisse (Diese enthält einige .xml-Dateien, SONDERN nur für Unit-tests oder Integrationstests - aber nicht für die beiden test-Typen zu einem bestimmten Zeitpunkt).
d.h. wenn ich "gradle clean build", dann wirst du sehen, Unit-test verwandt .xml-Dateien und
wenn ich "gradle clean build integrationTest", dann Unit-test .xml-Dateien werden überschrieben
und die .xml-Dateien, die ich sehen, sind nur mit/durch Sie erzeugten task integrationTest.
Folgende ist eine der häufigsten gradle (GRADLE_HOME/init.d/manche.common.gradle-Datei)
//
//Extra file can hold global Gradle settings so that these dont have to be inserted in project
//specific build.gradle file.
//Filename: extraN.common<anyname>.gradle
allprojects {
apply plugin: 'java'
apply plugin: 'pmd'
apply plugin: 'findbugs'
apply plugin: 'checkstyle'
apply plugin: 'jacoco'
apply plugin: 'sonar-runner'
tasks.withType(Compile) {
options.debug = true
options.compilerArgs = ["-g"]
}
sourceSets {
main {
java {
//MOTE: If your project's build.gradle specify the sourceSet section, the following
//values will be overwritten by what project's build.gradle will set.
//
//If you project's sourceSet structure if different in each project, then in this
//global common .gradle file, you can define srcDir for main or other sections like
//test, integrationTest etc as shown below -- commented out. If that's the case,
//then uncomment the below line and comment out using //-- srcDir 'src/java' line
//for sourceSets.main.java section. This rule applies to other sections as well.
//srcDir 'no_src_dir_set_yet'
srcDir 'src/java'
}
resources {
srcDir 'conf'
}
}
test {
java {
srcDir 'test/java'
}
resources {
srcDir 'test/resources'
srcDir 'conf'
}
}
integrationTest {
java {
srcDir 'src/java-test'
}
resources {
srcDir 'conf'
}
}
}
def sonarServerUrl = "dev.sandbox.server.com"
sonarRunner {
sonarProperties {
property "sonar.host.url", "http://$sonarServerUrl:9000"
property "sonar.jdbc.url", "jdbc:h2:tcp://$sonarServerUrl:9092/sonar"
property "sonar.jdbc.driverClassName", "org.h2.Driver"
property "sonar.jdbc.username", "sonar"
property "sonar.jdbc.password", "sonar"
properties ["sonar.sources"] += sourceSets.main.allSource.srcDirs
//properties ["sonar.tests"] += sourceSets.test.java.srcDirs
properties ["sonar.tests"] += sourceSets.integrationTest.allSource.srcDirs
}
}
checkstyle {
configFile = new File(rootDir, "config/checkstyle.xml")
ignoreFailures = true
//sourceSets = [sourceSets.main, sourceSets.test, sourceSets.integrationTest]
sourceSets = [sourceSets.main]
}
findbugs {
ignoreFailures = true
sourceSets = [sourceSets.main]
}
pmd {
ruleSets = ["basic", "braces", "design"]
ignoreFailures = true
}
jacoco {
toolVersion = "0.6.2.201302030002"
reportsDir = file("$buildDir/customJacocoReportDir")
}
task testReport(type: TestReport) {
destinationDir = file("$buildDir/reports/allTests")
}
test {
jacoco {
//destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
destinationFile = file("$buildDir/jacoco/test.exec")
//classDumpFile = file("$buildDir/jacoco/classpathdumps")
classDumpFile = file("$buildDir/build/classes/test")
}
}
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml{
enabled true
destination "${buildDir}/reports/jacoco/jacoco.xml"
}
csv.enabled false
html{
enabled true
destination "${buildDir}/jacocoHtml"
}
}
additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
//additionalSourceDirs = files([sourceSets.main.allJava.srcDirs, xxxx, 'xxxxyyyy' ])
}
}
bauen.gradle - Datei sieht wie folgt aus:
import com.tr.ids.gradle.CustomFileUtil
apply plugin: 'CustomSetup'
apply plugin: 'java'
apply plugin: 'customJarService'
apply plugin: 'customWarService'
sourceSets {
main {
java {
srcDir 'src/java'
}
}
test {
java {
srcDir 'test/java'
}
resources {
srcDir 'test/resources'
srcDir 'conf'
}
}
integrationTest {
java {
srcDir 'src/java-test'
}
}
}
//Read dependency lists from external files. Our custom plugin reads a dep-xxx.txt file for compile/test/war related .jar file entries
//where each entry is like: groupid:artifactid:x.x.x
//and these artifact jars are available in Artifactory
List depListCompile = customFileUtil.readIntoList( "$projectDir/dep-compile.txt" )
List depListTest = customFileUtil.readIntoList( "$projectDir/dep-testArtifacts.txt" )
List depListWar = customFileUtil.readIntoList( "$projectDir/dep-war.txt" )
//Define dependencies
dependencies {
//Compilation
compile depListCompile
//Unit Tests
testCompile depListTest
//Integration tests
//Everything from compile and testCompile targets
integrationTestCompile configurations.compile
integrationTestCompile configurations.testCompile
//Output of compiling "main" files
integrationTestCompile sourceSets.main.output
//Additional dependencies from war and others
integrationTestCompile depListTest, depListWar
//All configuration files
integrationTestRuntime files( 'conf' )
}
task deployTomcat( type: Copy, dependsOn: [ jar, compileIntegrationTestJava, warService ] ) {
from "$buildDir/customWar/${project.name}.war"
into "$projectDir/tomcat/webapps"
}
build {
dependsOn deployTomcat
}
task integrationTest( type: Test, dependsOn: cleanTest ) {
jacoco {
//destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
destinationFile = file("$buildDir/jacoco/integrationTest.exec")
//classDumpFile = file("$buildDir/jacoco/classpathdumps")
classDumpFile = file("$buildDir/classes/integrationTest")
}
testClassesDir = sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
}
apply plugin: 'eclipse'
eclipse.classpath {
//Define output directory so Eclipse does not accidentally clobber /bin
defaultOutputDir = file( 'out/classes' )
//Add integration test
plusConfigurations += configurations.integrationTestCompile
//Remove unnecessary files
file.whenMerged { classpath ->
classpath.entries.removeAll { entry -> ( entry.path.indexOf( '/build/classes/main' ) > 0 ) }
classpath.entries.removeAll { entry -> ( entry.path.indexOf( '/build/resources/main' ) > 0 ) }
}
}
Meine Fragen:
1) Warum "gradle clean build integrationTest" -- die erfolgreich arbeitet, ist das überschreiben von Testergebnissen in build/Berichte/tests und build - /test-Ergebnisse-Ordner.
2) Es ist egal, welchen Namen ich geben für .exec-Datei unter common gradle-Datei für test und im Aufbau.gradle für integrationTest Aufgabe für jacoco, es immer schaffen test.exec-und integrationTest.exec-Datei, aber die daraus resultierenden Bau - /jacocoHtml Ordner index.html Datei nicht zeigen Abdeckung /Dateien sowohl in Bezug auf Unit - /Integration-tests. Um dies zu beweisen, wenn ich "gradle clean build integrationTest jacocoTestReport sonarRunner", sehe ich den workspace für den job, jetzt enthält, ".sonar" - Ordner und erstellen/Berichte/sonar-Ordner enthält eine weitere Datei namens "insgesamt-xxx.exec" - Datei, aber die Datei Größe ist nicht in der Nähe der "Summe" der Unit-test.exec-und integrationTest.exec-Datei-Größe. Obwohl die größer als test.exec-Datei-Größe von wenigen bytes.
3) Welche Konfiguration kann ich einstellen, dass generell Versicherungsschutz für beide Einheiten und Prüfungen, d.h. insgesamt...exec-Datei bekommt eine gute Größe (nach dem sonarRunner Aufgabe). Während sonarRunner Aufgabe sehe ich SonarRunner Aufgabe "jacocoSensor Schritt" sieht beide UT und IT .exec-Dateien und die Allgemeine .exec-Datei als auch automatisch (ein gutes feature von Sonar).
InformationsquelleAutor Arun Sangal | 2013-09-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gefunden Antwort zu meiner 2. Frage. High-level info:
Gradle 1.6 jacocoTestReport benutzt verschiedene Variablen, Gradle >=1.7 verwendet verschiedene.
Ex: wir optimieren können, Unit-tests und Integration-Tests .exec-Datei erstellen, indem Sie "test" oder "integrationTest" Aufgabe, indem Sie die RICHTIGEN Variablen -oder es wird nicht funktionieren, n generieren "test.exec" und "integrationTest.exec" Standard-Datei-Namen. Siehe Beispiel unten.
task integrationTest(Typ: Test) ODER test { ... } - Abschnitt können die richtigen Variablen für den gegebenen Gradle-version, die wir verwenden.
Ebenso für test { .... } Aufgabe können Sie definieren es als ../../UT/jacocoUT.exec ../../UT/classpathdumps...
.sonar-Ordner angelegt wird, wenn ich "sonar-runner" Linux - /Unix-sonar-runner in meinem Projekt für den Arbeitsbereich, ABER wenn ich Jenkins-job, der fordert, Gradle "clean build integrationTest jacocoTestReport sonarRunner", dann bauen/sonar-Ordner erstellt und wird die ARBEIT DIR für SONAR (dies zeigt sich bei der Ausgabe).
In Jenkins > unter Post-build-Abschnitt, erwähnte ich die folgenden und JETZT, jacoco code coverage report auf Jenkins-Dashboard für beide jacoco-Dateien (.html und .xml) inklusive Unit-und Integrationstests, code-coverage-Daten.
Datensatz Jacoco-coverage-Bericht Abschnitt Jenkins hat die folgenden Felder:
Die ich erwähnt habe:
Pfad exec-Dateien: /build/jacoco/UT/jacocoUT.exec, */build/jacoco/ES/jacocoIT.exec
Pfad zur Klasse dirs: */build/jacoco//classpathdumps/com/thc
(dies ist die Stelle, wo Jacoco instrumentierten Klassen sitzen).. beide bauen/jacoco/UT/classpathdumps/com/thc und bauen/jacoco/ES/classpathdumps/com/thc abgeholt werden ** ersetzt wird, für alle Ordner unter build/jacoco. dieser Wert kann auf "build/classes" Ordner als gut.
Pfad zu den Quellcode-Dateien: **
(wenn ich src/java, einige der links für die source-Datei nicht funktionieren, d.h. der Inhalt der Datei nicht angezeigt).. * * .. es funktioniert jetzt.
restlichen Felder leer gelassen.
In diesem Punkt bin ich in der Lage, um zu sehen, Jacoco code coverage für beide Einheiten-und Integrationstests, d.h. über den Besuch der Jacoco code coverage Bild am job-dashboard und Besuch der source-code-links und auch wenn Sie gehen und suchen "build/reports/jacoco/html/index.html" oder "build/jacocoHtml/index.html" Datei.
Immer noch versuchen, herauszufinden, was getan werden muss, damit SONAR diese pick 2 .exec-Dateien (ich habe gültige Werte gesetzt, die für sonar.xxx variurs Variablen für Quellen, tests, binaries, ...reportsPath etc für UT /IT-exec-Dateien... auf SonarQube dashboard, Unit-test-Abdeckung ist zeigt sich gut, aber Integration tests-Abdeckung ist immer noch bei 0,0%.
Ich werde fügen Sie die Kopie meiner beiden gemeinsam.gradle und Projekt bauen.gradle Datei bald .... um besser sehen zu können.
InformationsquelleAutor Arun Sangal
OK, die Lösung gefunden zu UT/IT Ordner-Problem und meine Frage (1) in diesem Beitrag. Es ist eigentlich die "cleanTest" Aufgabe, die ein von der default-REGEL in Gradle.
Läuft "gradle-tasks -all" gibt, eine große Leistung der Aufgaben, die Gradle unterstützt und diese Ausgabe am Ende sagt über solche Regeln, wo, wenn wir sauber nennen, dann werde es wischen diesen Ordner. Wie Sie sehen in meinem code oben, integrationTest war abhängig von cleanTest, damit, wenn ich als "gradle clean build integrationTest" es lief Einheiten, die ersten tests (über build-Aufgabe als Unit-tests läuft standardmäßig mit dem build-Schritt in Gradle) und dann integration-tests über "integrationTest" Aufgabe, deshalb, während der Ausführung von Integrations-tests, genannt cleanTest Aufgabe, die ausgelöscht "UT" - Ordner, die ich erwähnt habe, in einer gemeinsamen gradle-Skript (/init.d/commmon-einige-Namen.gradle-Datei) wie ich bereits erwähnt habe ES Ordner für Berichte/Ergebnisse-Verzeichnisse.
Entfernen cleanTest als dependsOn von integrationTest Aufgabe, gelöst wischen-out-Problem.
Die Ausgabe des folgenden Befehls: zeigt nur die letzten paar Zeilen...
gradle-tasks -alle
Gefunden: Don ' T use "dependsOn cleanTest" in der task integrationTest.und Ausgänge verwenden.xxx {faslse} innerhalb integrationTest Aufgabe: - Ausgänge.upToDateWhen { false } --- Dadurch wird der task integrationTest laufen immer und auch als wir den Aufruf nicht dependsOn cleanTest, werde es nicht löschen, UT Ordner für Unit-tests während SIE die Erstellung von Ordnern/integrationTest Aufgabe ausführen. Wenn Sie möchten, erstellen Sie frisch Ordner für jedes mal, wenn es läuft, dann erstellen Sie eine Aufgabe: Aufgabe integTest { ...definieren diese 2 testxxxDir Werte innerhalb integTest ... } und nun kann man mit "dependsOn cleanIntegTest" integrationTest Aufgabe.
InformationsquelleAutor Arun Sangal