Gradle: Wie werden Testergebnisse in Echtzeit in der Konsole angezeigt?

231

Ich möchte Testergebnisse sehen (system.out / err, Protokollmeldungen von zu testenden Komponenten), wie sie in derselben Konsole ausgeführt werden, die ich ausführe:

gradle test

Und warten Sie nicht, bis die Tests abgeschlossen sind, um die Testberichte anzuzeigen (die erst generiert werden, wenn die Tests abgeschlossen sind, sodass ich während der Ausführung der Tests nichts "verfolgen" kann).

Tolitius
quelle

Antworten:

169

Sie können Gradle mit der INFO-Protokollierungsstufe in der Befehlszeile ausführen. Es zeigt Ihnen das Ergebnis jedes Tests, während sie ausgeführt werden. Nachteil ist, dass Sie auch für andere Aufgaben viel mehr Output erhalten.

gradle test -i
Benjamin Muschko
quelle
13
Mit 1.0-Meilenstein 6 können Sie das Gradle DSL jetzt direkt mit testLogging.showStandardStreams = true innerhalb des testAbschlusses konfigurieren .
Benjamin Muschko
4
Dies funktioniert in Gradle 1.11 nicht. Ich bekomme viel Debug-Ausgabe, aber nicht die einzelnen Testergebnisse.
David Moles
43
Das -iwird eine Menge irrelevanter Infos auf das Terminal werfen.
Thuy Trinh
9
Zusätzlich zu vielen nutzlosen Ausgaben wird für Tests, die bestehen und keine Ausgabe generieren, nichts angezeigt.
Toolbear
1
Sie können grepdamit Tausende von unerwünschten Zeilen herausfiltern. Siehe stackoverflow.com/questions/3963708/…
Mr-IDE
172

Hier ist meine schicke Version:

ausgefallenes Testergebnis

import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

tasks.withType(Test) {
    testLogging {
        // set options for log level LIFECYCLE
        events TestLogEvent.FAILED,
               TestLogEvent.PASSED,
               TestLogEvent.SKIPPED,
               TestLogEvent.STANDARD_OUT
        exceptionFormat TestExceptionFormat.FULL
        showExceptions true
        showCauses true
        showStackTraces true

        // set options for log level DEBUG and INFO
        debug {
            events TestLogEvent.STARTED,
                   TestLogEvent.FAILED,
                   TestLogEvent.PASSED,
                   TestLogEvent.SKIPPED,
                   TestLogEvent.STANDARD_ERROR,
                   TestLogEvent.STANDARD_OUT
            exceptionFormat TestExceptionFormat.FULL
        }
        info.events = debug.events
        info.exceptionFormat = debug.exceptionFormat

        afterSuite { desc, result ->
            if (!desc.parent) { // will match the outermost suite
                def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)"
                def startItem = '|  ', endItem = '  |'
                def repeatLength = startItem.length() + output.length() + endItem.length()
                println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
            }
        }
    }
}
Shubham Chaudhary
quelle
13
Meiner Meinung nach ist dies hier die beste Antwort. Es enthält die meisten Optionen und jeder kann seine Tests nach Bedarf konfigurieren.
Slawisch
2
@sealskej Wo muss ich diesen Code kopieren und wie kann ich ihn über die Befehlszeile ausführen? EDIT: verstanden - einfach zur gradle.config des Moduls hinzufügen und normal
ausführen
Nett! Ich habe gerade die Pipes |aus dem entfernt, startItemweil das Ausführen der Aufgabe über Android Studio 2.2.3 sie als Fehler in Nachrichten erkennt und es bei erfolgreichen Builds ärgerlich war.
Madlymad
1
Und wie haben Sie die Farben aktiviert?
Durga Swaroop
1
@ DurgaSwaroop Funktioniert sofort für mich. Stellen Sie sicher, dass Ihre Terminalanwendung Farben unterstützt. Ich persönlich benutze die iTerm2 App.
Shubham Chaudhary
156

Sie können Ihrer build.gradle-Datei einen Groovy-Abschluss hinzufügen, der die Protokollierung für Sie übernimmt:

test {
    afterTest { desc, result -> 
        logger.quiet "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
    }
}

Auf Ihrer Konsole lautet es dann wie folgt:

:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:jar
:assemble
:compileTestJava
:compileTestGroovy
:processTestResources
:testClasses
:test
Executing test maturesShouldBeCharged11DollarsForDefaultMovie [movietickets.MovieTicketsTests] with result: SUCCESS
Executing test studentsShouldBeCharged8DollarsForDefaultMovie [movietickets.MovieTicketsTests] with result: SUCCESS
Executing test seniorsShouldBeCharged6DollarsForDefaultMovie [movietickets.MovieTicketsTests] with result: SUCCESS
Executing test childrenShouldBeCharged5DollarsAnd50CentForDefaultMovie [movietickets.MovieTicketsTests] with result: SUCCESS
:check
:build

Seit Version 1.1 unterstützt Gradle viel mehr Optionen zum Protokollieren der Testausgabe . Mit diesen Optionen können Sie eine ähnliche Ausgabe mit der folgenden Konfiguration erzielen:

test {
    testLogging {
        events "passed", "skipped", "failed"
    }
}
stefanglase
quelle
4
Dies erzeugt die Ausgabe erst, nachdem der Test ausgeführt wurde. Was ich suche, ist, die Protokollierung / Berichterstellung / Systemausgänge / Ausdrucke usw. zu sehen, während Tests ausgeführt werden . Denken Sie daran, Tests mit maven oder nur in IntelliJ / Eclipse durchzuführen: Die Ausgabe wird in Echtzeit erzeugt.
Tolitius
Okay, entschuldigen Sie das Missverständnis Ihrer Frage. Für diesen Fall sollten Sie sich den folgenden Teil der Gradle-Dokumentation ansehen
stefanglase
1
Welche Änderung nehme ich tatsächlich vor, um die Ausgabe zu sehen? Ich sehe all diese benutzerdefinierten Listener und Dinge in der Dokumentation, aber ich habe keine Ahnung, wie ich das konfigurieren soll.
Jpswain
118

Als stefanglase antwortete:

Das Hinzufügen des folgenden Codes zu Ihrem build.gradle(seit Version 1.1) funktioniert einwandfrei für die Ausgabe bei bestandenen , übersprungenen und fehlgeschlagenen Tests.

test {
    testLogging {
        events "passed", "skipped", "failed", "standardOut", "standardError"
    }
}

Was ich zusätzlich sagen möchte (ich habe herausgefunden, dass dies für den Anfang ein Problem ist), ist, dass der gradle testBefehl den Test nur einmal pro Änderung ausführt .

Wenn Sie es also das zweite Mal ausführen, werden die Testergebnisse nicht ausgegeben . Sie können dies auch in der Gebäudeausgabe sehen: gradle sagt dann bei Tests UP-TO-DATE . Es wird also nicht zum n-ten Mal ausgeführt.

Smart Gradle!

Wenn Sie die Ausführung der Testfälle erzwingen möchten, verwenden Sie gradle cleanTest test.

Dies ist etwas abseits des Themas, aber ich hoffe, es wird einigen Neulingen helfen.

bearbeiten

Wie in den Kommentaren angegeben, sparc_spread :

Wenn Sie gradle erzwingen wollen immer laufen neue Prüfungen (die immer vielleicht keine gute Idee sein) können Sie hinzufügen outputs.upToDateWhen {false}zu testLogging { [...] }. Lesen Sie hier weiter .

Frieden.

Langusten Gustel
quelle
11
Hey, ich wollte dich nur wissen lassen, dass ich einen Weg gefunden habe, nicht gradle cleanTest testjedes Mal etwas sagen zu müssen (ab Gradle 1.12). Hinzufügen outputs.upToDateWhen {false}zu testLogging {...}und das sollte den Trick tun. Gradle wird gezwungen, die Tests jedes Mal auszuführen. Ich habe dies in den Gradle-Foren gefunden, die von Dockter selbst gepostet wurden . Hoffe das hilft.
sparc_spread
Ich würde exceptionFormat "full"hinzufügen, um Details darüber zu erhalten, was fehlgeschlagen ist, nützlich, wenn Sie AssertJ oder eine ähnliche Bibliothek verwenden.
Shairon Toledo
5
Anstelle von cleanTestIhnen könnentest --rerun-tasks
Gavenkoa
2
@gavenkoa Ich denke --rerun-tasks, dass alle Ihre Aufgaben erneut ausgeführt werden, nicht nur die Aufgaben für die Tests.
ThomasW
2
Eigentlich cleanTest testfunktioniert das neueste Android Studio und Gradle 3.3 nicht auf meiner Seite, hat aber --rerun-tasksden Trick gemacht. Ich weiß nicht warum. Aber das Lesen dieser Antwort hat meine Kopfschmerzen wirklich gelöst. Wo ist die Protokollierung des Testes, nachdem ich alles hinzugefügt habe?
Wingzero
111

Haftungsausschluss: Ich bin der Entwickler des Gradle Test Logger Plugins.

Sie können einfach das Gradle Test Logger Plugin verwenden , um schöne Protokolle auf der Konsole zu drucken. Das Plugin verwendet sinnvolle Standardeinstellungen, um die meisten Benutzer mit wenig oder keiner Konfiguration zufrieden zu stellen, bietet aber auch eine Reihe von Themen und Konfigurationsoptionen für jeden Geschmack.

Beispiele

Standardthema Standardthema

Mokka-Thema Mokka-Thema

Verwendung

plugins {
    id 'com.adarshr.test-logger' version '<version>'
}

Stellen Sie sicher, dass Sie immer die neueste Version von Gradle Central erhalten .

Aufbau

Sie benötigen überhaupt keine Konfiguration. Das Plugin bietet jedoch einige Optionen. Dies kann wie folgt erfolgen (Standardwerte werden angezeigt):

testlogger {
    // pick a theme - mocha, standard, plain, mocha-parallel, standard-parallel or plain-parallel
    theme 'standard'

    // set to false to disable detailed failure logs
    showExceptions true

    // set to false to hide stack traces
    showStackTraces true

    // set to true to remove any filtering applied to stack traces
    showFullStackTraces false

    // set to false to hide exception causes
    showCauses true

    // set threshold in milliseconds to highlight slow tests
    slowThreshold 2000

    // displays a breakdown of passes, failures and skips along with total duration
    showSummary true

    // set to true to see simple class names
    showSimpleNames false

    // set to false to hide passed tests
    showPassed true

    // set to false to hide skipped tests
    showSkipped true

    // set to false to hide failed tests
    showFailed true

    // enable to see standard out and error streams inline with the test results
    showStandardStreams false

    // set to false to hide passed standard out and error streams
    showPassedStandardStreams true

    // set to false to hide skipped standard out and error streams
    showSkippedStandardStreams true

    // set to false to hide failed standard out and error streams
    showFailedStandardStreams true
}

Ich hoffe, Sie werden es genießen, es zu benutzen.

adarshr
quelle
3
Nett! Erstaunlich etwas so Einfaches wie eine Zusammenfassung der bestandenen / fehlgeschlagenen / übersprungenen Tests führte dazu.
MarkHu
Ich habe gerade das Plugin integriert, aber ich sehe nicht, wie lange Tests dauern, wie in Ihrem Git für jeden Test in Klammern (1.6s). Wie kann ich das aktivieren?
dk7
@ dk7 Standardmäßig wird nur Tests gedruckt, deren Ausführung länger als 1 Sekunde dauert. Weitere Informationen finden Sie in der Dokumentation . Wenn Sie alle Dauern anzeigen möchten, stellen Sie einfach slowThresholdauf ein 0.
Adarshr
1
@ HaroldL.Brown Ja in der Tat :) Ich bin momentan nur ein bisschen überfüllt mit ein paar Dingen, aber es ist sehr lebendig.
Adarshr
1
Yup @VadymTyemirov. Das gleiche wie github.com/radarsh/gradle-test-logger-plugin/issues/137, sobald ich es dokumentiert habe ad
adarshr
49

Fügen Sie dies hinzu, um build.gradlezu verhindern, dass Gradle stdout und stderr verschluckt.

test {
    testLogging.showStandardStreams = true
}

Es ist hier dokumentiert .

Darwin
quelle
38

Die 'Test'-Aufgabe funktioniert nicht für das Android-Plugin. Verwenden Sie für das Android-Plugin Folgendes:

// Test Logging
tasks.withType(Test) {
    testLogging {
        events "started", "passed", "skipped", "failed"
    }
}

Siehe folgendes: https://stackoverflow.com/a/31665341/3521637

user3521637
quelle
3
Genial. FYI Future me - sparen Sie Ihre zwei Minuten, indem Sie es nicht in Android {} Block
Shubham Chaudhary
18

Als Folge von Shubhams großartiger Antwort möchte ich vorschlagen, Enum- Werte anstelle von Zeichenfolgen zu verwenden . Bitte schauen Sie sich die Dokumentation der TestLogging-Klasse an .

import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

tasks.withType(Test) {
    testLogging {
        events TestLogEvent.FAILED,
               TestLogEvent.PASSED,
               TestLogEvent.SKIPPED,
               TestLogEvent.STANDARD_ERROR,
               TestLogEvent.STANDARD_OUT
        exceptionFormat TestExceptionFormat.FULL
        showCauses true
        showExceptions true
        showStackTraces true
    }
}
JJD
quelle
12

Meine minimalistische Lieblingsversion basiert auf der Antwort von Shubham Chaudhary. Geben Sie hier die Bildbeschreibung ein

Legen Sie dies in die build.gradleDatei:

test {
    afterSuite { desc, result ->
    if (!desc.parent)
        println("${result.resultType} " +
            "(${result.testCount} tests, " +
            "${result.successfulTestCount} successes, " +
            "${result.failedTestCount} failures, " +
            "${result.skippedTestCount} skipped)")
    }
}
Andrzej Rehmann
quelle
7

In Gradle mit Android-Plugin:

gradle.projectsEvaluated {
    tasks.withType(Test) { task ->
        task.afterTest { desc, result ->
            println "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
        }
    }
}

Dann wird die Ausgabe sein:

Ausführen von test testConversionMinutes [org.example.app.test.DurationTest] mit Ergebnis: SUCCESS

Radeklos
quelle
3

Merge von Shubhams großartiger Antwort und JJD verwenden Enum anstelle von String

tasks.withType(Test) {
   testLogging {
       // set options for log level LIFECYCLE
       events TestLogEvent.PASSED,
            TestLogEvent.SKIPPED, TestLogEvent.FAILED, TestLogEvent.STANDARD_OUT
       showExceptions true
       exceptionFormat TestExceptionFormat.FULL
       showCauses true
       showStackTraces true

    // set options for log level DEBUG and INFO
       debug {
        events TestLogEvent.STARTED, TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED, TestLogEvent.STANDARD_OUT, TestLogEvent.STANDARD_ERROR
        exceptionFormat TestExceptionFormat.FULL
       }
       info.events = debug.events
       info.exceptionFormat = debug.exceptionFormat

       afterSuite { desc, result ->
           if (!desc.parent) { // will match the outermost suite
               def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
               def startItem = '|  ', endItem = '  |'
               def repeatLength = startItem.length() + output.length() + endItem.length()
               println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
           }
       }
   }
}
odemolliens
quelle
2
Ich bitte Sie, Ihrer Antwort einen weiteren Kontext hinzuzufügen. Nur-Code- oder Nur-Link-Antworten sind schwer zu verstehen. Es wird sowohl dem Fragesteller als auch zukünftigen Lesern helfen, wenn Sie Ihrem Beitrag weitere Informationen hinzufügen können.
RBT
2

In Anlehnung an die Antwort von Benjamin Muschko (19. März 2011) können Sie die -iFlagge zusammen mit grep verwenden , um Tausende unerwünschter Zeilen herauszufiltern. Beispiele:

Starker Filter - Zeigt nur den Namen und das Ergebnis jedes Komponententests sowie den gesamten Build-Status an. Setup-Fehler oder Ausnahmen werden nicht angezeigt.

./gradlew test -i | grep -E " > |BUILD"

Weicher Filter - Zeigt den Namen und das Ergebnis jedes Komponententests sowie Setup-Fehler / Ausnahmen an. Es wird aber auch einige irrelevante Informationen enthalten:

./gradlew test -i | grep -E -v "^Executing |^Creating |^Parsing |^Using |^Merging |^Download |^title=Compiling|^AAPT|^future=|^task=|:app:|V/InstrumentationResultParser:"

Weicher Filter, alternative Syntax: (Suchtoken werden in einzelne Zeichenfolgen aufgeteilt)

./gradlew test -i | grep -v -e "^Executing " -e "^Creating " -e "^Parsing " -e "^Using " -e "^Merging " -e "^Download " -e "^title=Compiling" -e "^AAPT" -e "^future=" -e "^task=" -e ":app:" -e "V/InstrumentationResultParser:"

Erläuterung der Funktionsweise: Die Ausgabe des ersten Befehls ./gradlew test -iwird an einen zweiten Befehl weitergeleitet grep, der viele unerwünschte Zeilen basierend auf einem regulären Ausdruck herausfiltert. "-E"aktiviert den regulären Ausdrucksmodus und "|"bedeutet "oder". Ein Komponententestname und ein Ergebnis dürfen mit angezeigt werden " > ", und der Gesamtstatus ist mit zulässig "BUILD". Im "-v"Softfilter bedeutet das Flag "nicht enthalten" und "^""Zeilenanfang". Es werden also alle Zeilen entfernt, die mit "Ausführen" oder "Erstellen" usw. beginnen.


Beispiel für Android Instrumentation Unit Tests mit Gradle 5.1:

./gradlew connectedDebugAndroidTest --continue -i | grep -v -e \
"^Transforming " -e "^Skipping " -e "^Cache " -e "^Performance " -e "^Creating " -e \
"^Parsing " -e "^file " -e "ddms: " -e ":app:" -e "V/InstrumentationResultParser:"

Beispiel für die Jacoco-Unit-Test-Abdeckung mit Gradle 4.10:

./gradlew createDebugCoverageReport --continue -i | grep -E -v "^Executing |^Creating |^Parsing |^Using |^Merging |^Download |^title=Compiling|^AAPT|^future=|^task=|:app:|V/InstrumentationResultParser:"
Mr-IDE
quelle
0

Wenn Sie ein build.gradle.ktsin Kotlin DSL geschriebenes haben , können Sie Testergebnisse mit drucken (ich habe ein kotlin Multi-Plattform-Projekt entwickelt, ohne dass ein "Java" -Plugin angewendet wurde):

tasks.withType<AbstractTestTask> {
    afterSuite(KotlinClosure2({ desc: TestDescriptor, result: TestResult ->
        if (desc.parent == null) { // will match the outermost suite
            println("Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)")
        }
    }))
}
Enrico
quelle