Gradle: Bagaimana Menampilkan Hasil Uji di Konsol dalam Waktu Nyata?


231

Saya ingin melihat hasil pengujian (system.out / err, mencatat pesan dari komponen yang sedang diuji) saat dijalankan di konsol yang sama dengan yang saya jalankan:

gradle test

Dan jangan menunggu sampai tes dilakukan untuk melihat laporan pengujian (yang hanya dihasilkan ketika tes selesai, jadi saya tidak bisa "mengekor-f" apa pun saat tes sedang berjalan)

Jawaban:


169

Anda bisa menjalankan Gradle dengan INFO level logging di baris perintah. Ini akan menunjukkan kepada Anda hasil dari setiap tes saat mereka sedang berjalan. Kekurangannya adalah bahwa Anda akan mendapatkan lebih banyak output untuk tugas-tugas lain juga.

gradle test -i

13
Dengan 1.0-milestone 6, Gradle DSL sekarang memungkinkan Anda mengonfigurasinya secara langsung menggunakan testLogging.showStandardStreams = true dalam testpenutupan.
Benjamin Muschko

4
Ini tidak berfungsi di kelas 1.11. Saya mendapatkan banyak hasil debug, tetapi bukan hasil tes individu.
David Moles

44
Itu -iakan membuang banyak info yang tidak relevan pada terminal.
Thuy Trinh

9
Selain banyak output yang tidak berguna, tidak ada yang ditampilkan untuk tes yang lulus dan tidak menghasilkan output.
Toolbear

1
Anda dapat menggunakan grepuntuk menyaring ribuan garis yang tidak diinginkan. Lihat stackoverflow.com/questions/3963708/…
Mr-IDE

172

Ini versi mewah saya:

hasil tes mewah

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

13
Menurut pendapat saya, ini adalah jawaban terbaik di sini. Ini berisi serangkaian opsi terbesar dan semua orang dapat mengonfigurasi tes mereka sesuai kebutuhan.
Slav

2
@ sealskej di mana saya harus menyalin kode ini dan bagaimana menjalankannya dari baris perintah? EDIT: mendapatkannya - tambahkan saja ke gradle.config modul dan berjalan secara normal
hardysim

Bagus! Saya baru saja menghapus pipa |dari startItemkarena menjalankan tugas melalui Android Studio 2.2.3 mengenalinya sebagai kesalahan dalam pesan dan itu mengganggu membangun sukses.
madlymad

1
Dan bagaimana Anda mengaktifkan warna?
Durga Swaroop

1
@ DurgaSwaroop Bekerja di luar kotak untuk saya. Pastikan aplikasi terminal Anda mendukung warna. Saya pribadi menggunakan aplikasi iTerm2.
Shubham Chaudhary

156

Anda bisa menambahkan penutupan Groovy di dalam file build.gradle Anda yang melakukan pendataan untuk Anda:

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

Di konsol Anda, bunyinya seperti ini:

: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

Karena versi 1.1 Gradle mendukung lebih banyak opsi untuk mencatat hasil tes . Dengan opsi-opsi tersebut, Anda dapat mencapai hasil yang serupa dengan konfigurasi berikut:

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

4
ini hanya akan menghasilkan output setelah pengujian dijalankan. apa yang saya cari adalah melihat logging / pelaporan / sistem out / printlns dll. saat tes sedang berjalan . pikirkan tentang menjalankan tes dengan pakar atau hanya di IntelliJ / Eclipse: output diproduksi secara real time.
tolitius

Oke, maaf karena salah mengerti pertanyaan Anda. Untuk itu Anda harus melihat bagian berikut dari dokumentasi Gradle
stefanglase

1
Jadi perubahan apa yang sebenarnya saya lakukan untuk melihat hasilnya? Saya melihat semua pendengar dan hal-hal khusus ini dalam dokumentasi, tetapi saya tidak tahu cara mengkonfigurasi ini.
jpswain

118

Sebagai stefanglase menjawab:

menambahkan kode berikut ke build.gradle(sejak versi 1.1) Anda berfungsi dengan baik untuk output pada tes yang lulus , dilewati dan gagal .

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

Apa yang ingin saya katakan tambahan (saya menemukan ini adalah masalah bagi pemula) adalah bahwa gradle testperintah menjalankan tes hanya satu kali per perubahan .

Jadi jika Anda menjalankannya untuk kedua kalinya tidak akan ada output pada hasil tes . Anda juga dapat melihat ini di output bangunan: gradle kemudian berkata UP-TO-DATE pada tes. Jadi tidak dieksekusi waktu ke-n.

Gradle cerdas!

Jika Anda ingin memaksa test case dijalankan, gunakan gradle cleanTest test .

Ini sedikit keluar dari topik tapi saya harap ini akan membantu beberapa pemula.

sunting

Sebagai sparc_spread dinyatakan di komentar:

Jika Anda ingin memaksa Gradle untuk tes segar selalu berjalan (yang mungkin tidak selalu menjadi ide yang baik) Anda dapat menambahkan outputs.upToDateWhen {false}untuk testLogging { [...] }. Lanjutkan membaca di sini .

Perdamaian.


11
Hei, hanya ingin memberi tahu Anda bahwa saya menemukan cara untuk tidak harus mengatakan gradle cleanTest testsetiap waktu (pada Gradle 1.12). Tambahkan outputs.upToDateWhen {false}ke testLogging {...}dan itu harus melakukan trik. Ini akan memaksa Gradle untuk menjalankan tes setiap saat. Saya menemukan ini di forum Gradle, diposting oleh Dockter sendiri . Semoga ini membantu.
sparc_spread

Saya akan menyertakan exceptionFormat "full"untuk mendapatkan detail tentang apa yang gagal, berguna ketika Anda menggunakan AssertJ atau lib serupa.
Shairon Toledo

5
Alih-alih cleanTestAnda dapat menggunakantest --rerun-tasks
gavenkoa

2
@gavenkoa Saya pikir --rerun-tasksakan membuat semua tugas Anda jalankan kembali, bukan hanya tugas untuk tes.
ThomasW

2
sebenarnya, cleanTest testpada Android Studio terbaru dan gradle 3.3 tidak bekerja di pihak saya, tetapi --rerun-tasksmelakukan trik Tidak tahu kenapa Tapi membaca jawaban ini benar-benar menyelesaikan sakit kepala saya, di mana tes f ** king logging setelah saya menambahkan semuanya.
Wingzero

111

Penafian: Saya adalah pengembang dari Plugin Logger Tes Gradle.

Anda cukup menggunakan Plugin Tes Logger Gradle untuk mencetak log yang indah di konsol. Plugin ini menggunakan default yang masuk akal untuk memuaskan sebagian besar pengguna dengan sedikit atau tanpa konfigurasi tetapi juga menawarkan sejumlah tema dan opsi konfigurasi yang sesuai untuk semua orang.

Contohnya

Tema Standar Tema standar

Tema Mocha Tema Mocha

Pemakaian

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

Pastikan Anda selalu mendapatkan versi terbaru dari Gradle Central .

Konfigurasi

Anda tidak memerlukan konfigurasi sama sekali. Namun, plugin ini menawarkan beberapa opsi. Ini dapat dilakukan sebagai berikut (nilai default yang ditampilkan):

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
}

Saya harap Anda akan menikmati menggunakannya.


3
Bagus! Mengagumkan sesuatu yang sederhana seperti ringkasan dari tes yang lulus / gagal / dilewati menyebabkannya.
MarkHu

Saya baru saja mengintegrasikan plugin, tapi saya tidak melihat tes durasi mengambil, seperti di git Anda untuk setiap tes dalam tanda kurung (1.6s) Bagaimana cara mengaktifkannya?
dk7

@ dk7 secara default, hanya tes yang membutuhkan waktu lebih dari 1 detik untuk dijalankan akan memiliki durasi dicetak. Lihat dokumentasi untuk info lebih lanjut. Jika Anda ingin melihat semua jangka waktu, cukup setel slowThresholdke 0.
adarshr

1
@ HaroldL. Brown Ya memang :) Saya hanya sedikit dibanjiri dengan beberapa hal saat ini tetapi sangat hidup.
adarshr

1
Yup @VadymTyemirov. Sama seperti github.com/radarsh/gradle-test-logger-plugin/issues/137 begitu saya mendokumentasikannya ad
adarshr

49

Tambahkan ini untuk build.gradlemenghentikan gradle dari menelan stdout dan stderr.

test {
    testLogging.showStandardStreams = true
}

Sudah didokumentasikan di sini .



18

Sebagai tindak lanjut dari jawaban hebat Shubham, saya ingin menyarankan menggunakan nilai enum alih-alih string . Silakan lihat dokumentasi kelas 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
    }
}

12

Versi minimalis favorit saya berdasarkan jawaban Shubham Chaudhary. masukkan deskripsi gambar di sini

Masukkan ini ke dalam build.gradlefile:

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

7

Di Gradle menggunakan plugin Android:

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

Maka outputnya adalah:

Menjalankan tes testConversionMinutes [org.example.app.test.DurationTest] dengan hasil: SUKSES


3

Menggabungkan jawaban hebat Shubham dan JJD menggunakan enum sebagai ganti 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))
           }
       }
   }
}

2
Saya meminta Anda untuk menambahkan beberapa konteks di sekitar jawaban Anda. Jawaban hanya kode atau hanya tautan sulit untuk dipahami. Ini akan membantu penanya dan pembaca di masa mendatang jika Anda dapat menambahkan lebih banyak informasi dalam posting Anda.
RBT

2

Sebagai lanjutan dari jawaban Benjamin Muschko (19 Maret 2011), Anda dapat menggunakan -ibendera bersama dengan grep , untuk memfilter ribuan garis yang tidak diinginkan. Contoh:

Filter yang kuat - Hanya menampilkan setiap nama tes dan hasil unit, dan status build keseluruhan. Kesalahan atau pengecualian penyiapan tidak ditampilkan.

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

Filter lunak - Menampilkan setiap nama dan hasil pengujian unit, serta kesalahan pengaturan / pengecualian. Tetapi itu juga akan mencakup beberapa info yang tidak relevan:

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

Filter lunak, Sintaks alternatif: (token pencarian dibagi menjadi string individual)

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

Penjelasan tentang cara kerjanya: Output dari perintah pertama,, ./gradlew test -idisalurkan ke perintah kedua grep, yang akan menyaring banyak baris yang tidak diinginkan berdasarkan ekspresi reguler. "-E"mengaktifkan mode ekspresi reguler, dan "|"berarti "atau". Nama dan hasil uji unit diizinkan untuk ditampilkan menggunakan " > ", dan status keseluruhan diizinkan dengan "BUILD". Di filter lunak, "-v"bendera berarti "tidak mengandung" dan "^"berarti "mulai dari garis". Jadi menghapus semua baris yang dimulai dengan "Eksekusi" atau mulai dengan "Membuat", dll.


Contoh untuk tes unit instrumentasi Android, dengan 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:"

Contoh untuk cakupan tes unit Jacoco, dengan gradle 4.10:

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

0

Jika Anda memiliki build.gradle.ktstulisan di Kotlin DSL Anda dapat mencetak hasil tes dengan (saya sedang mengembangkan proyek multi-platform kotlin, tanpa plugin "java" diterapkan):

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

0

Tambahkan saja penutupan berikut ke build.gradle Anda. output akan dicetak setelah pelaksanaan setiap tes.

test{
    useJUnitPlatform()
    afterTest { desc, result ->
        def output = "Class name: ${desc.className}, Test name: ${desc.name},  (Test status: ${result.resultType})"
        println( '\n' + output)
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.