Gradle: ¿Cómo mostrar los resultados de la prueba en la consola en tiempo real?

231

Me gustaría ver los resultados de la prueba (system.out / err, mensajes de registro de los componentes que se están probando) mientras se ejecutan en la misma consola que ejecuto:

gradle test

Y no espere hasta que se realicen las pruebas para ver los informes de las pruebas (que solo se generan cuando se completan las pruebas, por lo que no puedo "seguir nada" mientras se ejecutan las pruebas)

Tolitius
fuente

Respuestas:

169

Puede ejecutar Gradle con el nivel de registro INFO en la línea de comando. Le mostrará el resultado de cada prueba mientras se ejecutan. Lo malo es que también obtendrá mucho más rendimiento para otras tareas.

gradle test -i
Benjamin Muschko
fuente
13
Con 1.0-milestone 6, el DSL de Gradle ahora le permite configurarlo directamente usando testLogging.showStandardStreams = true dentro del testcierre.
Benjamin Muschko
44
Esto no funciona en gradle 1.11. Obtengo muchos resultados de depuración, pero no los resultados de las pruebas individuales.
David Moles
44
Eso -iarrojará un montón de informaciones irrelevantes en la terminal.
Thuy Trinh
99
Además de una gran cantidad de resultados inútiles, no se muestra nada para las pruebas que pasan y no generan resultados.
toolbear
1
Puede usar greppara filtrar los miles de líneas no deseadas. Ver stackoverflow.com/questions/3963708/…
Mr-IDE
172

Aquí está mi versión elegante:

resultado de prueba de lujo

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
fuente
13
En mi opinión, esta es la mejor respuesta aquí. Contiene el mayor conjunto de opciones y todos pueden configurar sus pruebas según lo necesiten.
Eslavo
2
@sealskej ¿dónde necesito copiar este código y cómo ejecutarlo desde la línea de comandos? EDIT: lo consiguió - sólo tiene que añadir a gradle.config de los módulos y ejecutar normalmente
hardysim
¡Agradable! Acabo de eliminar las tuberías |del startItemporque ejecutar la tarea a través de Android Studio 2.2.3 los reconoce como errores en los mensajes y fue molesto en las compilaciones exitosas.
madlymad
1
¿Y cómo habilitaron los colores?
Durga Swaroop
1
@DurgaSwaroop Funciona fuera de la caja para mí. Asegúrese de que su aplicación de terminal admita colores. Yo personalmente uso la aplicación iTerm2.
Shubham Chaudhary
156

Puede agregar un cierre Groovy dentro de su archivo build.gradle que hace el registro por usted:

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

En su consola, se lee así:

: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

Desde la versión 1.1, Gradle admite muchas más opciones para registrar la salida de prueba . Con esas opciones disponibles, puede lograr un resultado similar con la siguiente configuración:

test {
    testLogging {
        events "passed", "skipped", "failed"
    }
}
stefanglase
fuente
44
esto solo producirá la salida después de ejecutar la prueba. lo que estoy buscando es ver el registro / informes / salidas del sistema / printlns, etc. a medida que se ejecutan las pruebas . piense en ejecutar pruebas con maven o solo en IntelliJ / Eclipse: la salida se produce en tiempo real.
tolitius
Bien, perdón por malinterpretar tu pregunta. Para ese caso, debería echar un vistazo a la siguiente parte de la documentación de Gradle
stefanglase
1
Entonces, ¿qué cambio realizo para ver la salida? Veo todos estos oyentes personalizados y otras cosas en la documentación, pero no tengo idea de cómo configurar esto.
jpswain
118

Como stefanglase respondió:

agregar el siguiente código a su build.gradle(desde la versión 1.1) funciona bien para la salida en pruebas aprobadas , omitidas y fallidas .

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

Lo que quiero decir adicionalmente (descubrí que esto es un problema para los principiantes) es que el gradle testcomando ejecuta la prueba solo una vez por cambio .

Entonces, si lo está ejecutando la segunda vez, no habrá salida en los resultados de la prueba . También puede ver esto en la salida del edificio: Gradle luego dice ARRIBA AL DÍA en las pruebas. Por lo tanto, no se ejecuta por enésima vez.

Gradle inteligente!

Si desea forzar la ejecución de los casos de prueba, use gradle cleanTest test.

Esto está un poco fuera de tema, pero espero que ayude a algunos novatos.

editar

Como sparc_spread declaró en los comentarios:

Si desea forzar Gradle a nuevos ensayos siempre se corre (que no siempre pueden ser una buena idea) se puede añadir outputs.upToDateWhen {false}a testLogging { [...] }. Sigue leyendo aquí .

Paz.

Langusten Gustel
fuente
11
Oye, solo quería hacerte saber que encontré una manera de no tener que decir gradle cleanTest testcada vez (a partir de Gradle 1.12). Añadir outputs.upToDateWhen {false}a testLogging {...}y que debe hacer el truco. Obligará a Gradle a ejecutar las pruebas cada vez. Encontré esto en los foros de Gradle, publicado por el mismo Dockter . Espero que esto ayude.
sparc_spread
Me incluyo exceptionFormat "full"para obtener detalles acerca de lo que falló, útil cuando se está utilizando AssertJ o IIb similar.
Shairon Toledo
55
En lugar de cleanTestque pueda usartest --rerun-tasks
gavenkoa
2
@gavenkoa, creo que --rerun-tasksvolverá a ejecutar todas sus tareas, no solo las tareas para las pruebas.
ThomasW
2
en realidad, cleanTest testen el último Android Studio y Gradle 3.3 no funciona de mi lado, pero --rerun-tasksfuncionó. No se porque. Pero leer esta respuesta realmente resolvió mi dolor de cabeza, ¿dónde está el registro de la prueba f ** king después de agregar todo?
Wingzero
111

Descargo de responsabilidad: soy el desarrollador del complemento Gradle Test Logger.

Simplemente puede usar el complemento Gradle Test Logger para imprimir hermosos registros en la consola. El complemento utiliza valores predeterminados razonables para satisfacer a la mayoría de los usuarios con poca o ninguna configuración, pero también ofrece una serie de temas y opciones de configuración para todos los gustos.

Ejemplos

Tema estándar Tema estándar

Tema Mocha Tema Mocha

Uso

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

Asegúrese de obtener siempre la última versión de Gradle Central .

Configuración

No necesita ninguna configuración en absoluto. Sin embargo, el complemento ofrece algunas opciones. Esto se puede hacer de la siguiente manera (se muestran los valores predeterminados):

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
}

Espero que disfrutes usándolo.

adarshr
fuente
3
¡Agradable! Sorprendente algo tan simple como un resumen de pruebas aprobadas / reprobadas / omitidas lo llevó a ello.
MarkHu
Acabo de integrar el complemento, pero no veo la duración de las pruebas, como en su git para cada prueba entre paréntesis (1.6s) ¿Cómo habilitar eso?
dk7
@ dk7 de forma predeterminada, solo las pruebas que tardan más de 1 segundo en ejecutarse tendrán impresa la duración. Vea la documentación para más información. Si desea ver todas las duraciones, simplemente configúrelo slowThresholden 0.
adarshr
1
@ HaroldL.Brown Sí, de hecho :) Estoy un poco abrumado con algunas cosas actualmente, pero está muy vivo.
adarshr
1
Sí, @VadymTyemirov. Lo mismo que github.com/radarsh/gradle-test-logger-plugin/issues/137 una vez que lo documente 🙂
adarshr
49

Agregue esto a build.gradlepara evitar que gradle trague stdout y stderr.

test {
    testLogging.showStandardStreams = true
}

Está documentado aquí .

Darwin
fuente
38

La tarea 'prueba' no funciona para el complemento de Android, para el complemento de Android use lo siguiente:

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

Consulte lo siguiente: https://stackoverflow.com/a/31665341/3521637

usuario3521637
fuente
3
Increíble. FYI Future me - ahorre sus dos minutos al no colocarlo dentro del bloque android {}
Shubham Chaudhary
18

Como seguimiento a la gran respuesta de Shubham, me gustaría sugerir el uso de valores de enumeración en lugar de cadenas . Por favor, eche un vistazo a la documentación de la clase TestLogging .

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
fuente
12

Mi versión minimalista favorita basada en la respuesta de Shubham Chaudhary. ingrese la descripción de la imagen aquí

Pon esto en el build.gradlearchivo:

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

En Gradle usando el complemento de Android:

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

Entonces la salida será:

Ejecutando test testConversionMinutes [org.example.app.test.DurationTest] con el resultado: ÉXITO

radeklos
fuente
3

Combinar la gran respuesta de Shubham y JJD usan enum en lugar de 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
fuente
2
Le solicito que agregue un poco más de contexto alrededor de su respuesta. Las respuestas de solo código o solo de enlace son difíciles de entender. Ayudará tanto al autor de la pregunta como a los futuros lectores si puede agregar más información en su publicación.
RBT
2

Siguiendo la respuesta de Benjamin Muschko (19 de marzo de 2011), puede usar la -ibandera junto con grep , para filtrar miles de líneas no deseadas. Ejemplos:

Filtro fuerte : solo muestra el nombre y el resultado de cada prueba de unidad, y el estado general de construcción. Los errores o excepciones de configuración no se muestran.

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

Filtro suave : muestra el nombre y el resultado de la prueba de cada unidad, así como los errores / excepciones de configuración. Pero también incluirá información irrelevante:

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

Filtro suave, sintaxis alternativa: (los tokens de búsqueda se dividen en cadenas individuales)

./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:"

Explicación de cómo funciona: la salida del primer comando, ./gradlew test -ise canaliza a un segundo comando grep, que filtrará muchas líneas no deseadas en función de una expresión regular. "-E"habilita el modo de expresión regular y "|"significa "o". Se puede mostrar un nombre de prueba de unidad y el resultado usando " > ", y el estado general se permite con "BUILD". En el filtro suave, la "-v"bandera significa "no contiene" y "^"significa "inicio de línea". Por lo tanto, elimina todas las líneas que comienzan con "Ejecutando" o comienzan con "Creando", etc.


Ejemplo para pruebas de unidad de instrumentación de Android, con 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:"

Ejemplo de cobertura de prueba de unidad Jacoco, con 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
fuente
0

Si tiene un DSL de Kotlinbuild.gradle.kts escrito , puede imprimir los resultados de la prueba con (estaba desarrollando un proyecto multiplataforma de Kotlin, sin el complemento "java" aplicado):

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
fuente
0

Simplemente agregue el siguiente cierre a su build.gradle. la salida se imprimirá después de la ejecución de cada prueba.

test{
    useJUnitPlatform()
    afterTest { desc, result ->
        def output = "Class name: ${desc.className}, Test name: ${desc.name},  (Test status: ${result.resultType})"
        println( '\n' + output)
    }
}
Solimán
fuente