Gradle: как отобразить результаты теста в консоли в режиме реального времени?

231

Я хотел бы видеть результаты тестирования (system.out / err, протоколировать сообщения от тестируемых компонентов), поскольку они запускаются в той же консоли, которую я запускаю:

gradle test

И не ждите, пока не будут выполнены тесты, чтобы посмотреть отчеты о тестах (которые генерируются только после завершения тестов, поэтому я не могу ничего «хвост -f» во время выполнения тестов)

tolitius
источник

Ответы:

169

Вы можете запустить Gradle с уровнем ведения журнала INFO в командной строке. Он покажет вам результаты каждого теста, пока они работают. Недостатком является то, что вы получите гораздо больший выход для других задач.

gradle test -i
Бенджамин Мущко
источник
13
С 1.0-вехой 6 Gradle DSL теперь давайте настроим это напрямую, используя testLogging.showStandardStreams = true в testзамыкании.
Бенджамин Мущко
4
Это не работает в Gradle 1.11. Я получаю много отладочной информации, но не отдельные результаты теста.
Дэвид Моулз
44
Это -iдобавит кучу ненужной информации на терминал.
Thuy Trinh
9
В дополнение к большому количеству бесполезного вывода, ничего не отображается для тестов, которые проходят и не генерируют вывод.
Toolbear
1
Вы можете использовать, grepчтобы отфильтровать тысячи нежелательных строк. См. Stackoverflow.com/questions/3963708/…
Mr-IDE
172

Вот моя модная версия:

необычный результат теста

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
На мой взгляд, это лучший ответ здесь. Он содержит самый большой набор параметров, и каждый может настроить свои тесты так, как ему нужно.
Славянин
2
@sealskej, куда мне нужно скопировать этот код и как запустить его из командной строки? РЕДАКТИРОВАТЬ: получил - просто добавьте его в модуль gradle.config и работайте как обычно
hardysim
Ницца! Я просто удалил каналы |из-за того, startItemчто запуск задачи через Android Studio 2.2.3 распознал их как ошибки в сообщениях, и это было неприятно при успешных сборках.
madlymad
1
А как ты включил цвета?
Дурга Сваруп
1
@DurgaSwaroop Работает из коробки для меня. Пожалуйста, убедитесь, что ваше терминальное приложение поддерживает цвета. Я лично использую приложение iTerm2.
Шубхам Чаудхари
156

Вы можете добавить Groovy-замыкание в свой файл build.gradle, который делает запись для вас:

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

На вашей консоли это выглядит так:

: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

Начиная с версии 1.1 Gradle поддерживает гораздо больше опций для записи результатов тестирования . Имея эти опции под рукой, вы можете получить аналогичный результат в следующей конфигурации:

test {
    testLogging {
        events "passed", "skipped", "failed"
    }
}
stefanglase
источник
4
это даст результат только после выполнения теста. то, что я ищу, чтобы увидеть журналы / отчеты / системные выходы / printlns и т. д., как тесты работают . подумайте о выполнении тестов с помощью Maven или просто в IntelliJ / Eclipse: вывод производится в режиме реального времени.
Толиций
Хорошо, извините за неправильное понимание вашего вопроса. Для этого случая вам следует взглянуть на следующую часть документации Gradle: gradle.org/logging.html#sec:external_tools
stefanglase
1
Итак, что я на самом деле делаю, чтобы увидеть результат? Я вижу все эти пользовательские слушатели и прочее в документации, но я не знаю, как это настроить.
jpswain
118

Как ответил Стефанглаз :

добавление следующего кода в ваш build.gradle(начиная с версии 1.1) отлично работает для вывода на пройденных , пропущенных и неудачных тестах.

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

Что я хочу сказать дополнительно (я обнаружил, что это проблема для начинающих), так это то, что gradle testкоманда выполняет тест только один раз за изменение .

Поэтому, если вы запускаете его во второй раз, результаты теста не будут отображаться . Вы также можете увидеть это в выводе здания: gradle говорит UP-TO-DATE на испытаниях. Так что не выполняется n-й раз.

Умный градл!

Если вы хотите принудительно запустить тестовые случаи, используйте gradle cleanTest test .

Это немного не по теме, но я надеюсь, что это поможет некоторым новичкам.

редактировать

Как sparc_spread указано в комментариях :

Если вы хотите, чтобы gradle всегда запускал новые тесты (что не всегда является хорошей идеей), вы можете добавить outputs.upToDateWhen {false}к testLogging { [...] }. Продолжить чтение здесь .

Мир.

Лангустен Густел
источник
11
Эй, просто хотел сообщить, что я нашел способ не говорить gradle cleanTest testкаждый раз (начиная с версии 1.12). Добавьте outputs.upToDateWhen {false}к этому, testLogging {...}и это должно помочь. Это заставит Gradle запускать тесты каждый раз. Я нашел это на форумах Gradle, опубликованных самим Доктером . Надеюсь это поможет.
sparc_spread
Я хотел бы exceptionFormat "full"получить подробную информацию о том, что не удалось, полезно, когда вы используете AssertJ или подобную библиотеку.
Шаирон Толедо
5
Вместо cleanTestтебя можно использоватьtest --rerun-tasks
gavenkoa
2
@gavenkoa Я думаю --rerun-tasks, что все ваши задачи будут выполняться повторно, а не только задачи для тестов.
ThomasW
2
на самом деле, cleanTest testна последней Android Studio и Gradle 3.3 не работает на моей стороне, но --rerun-tasksсделал свое дело. Не знаю почему. Но чтение этого ответа действительно решило мою головную боль, где записывается тест f ** king после того, как я добавляю каждую вещь.
Wingzero
111

Отказ от ответственности: я являюсь разработчиком плагина Gradle Test Logger.

Вы можете просто использовать плагин Gradle Test Logger для печати красивых журналов на консоли. Плагин использует разумные значения по умолчанию, чтобы удовлетворить большинство пользователей с минимальной или нулевой конфигурацией, но также предлагает ряд тем и опций конфигурации на любой вкус.

Примеры

Стандартная тема Стандартная тема

Тема мокко Мокко тема

использование

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

Убедитесь, что вы всегда получаете последнюю версию от Gradle Central .

конфигурация

Вам не нужно никаких настроек вообще. Тем не менее, плагин предлагает несколько вариантов. Это можно сделать следующим образом (показаны значения по умолчанию):

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
}

Я надеюсь, вам понравится его использовать.

adarshr
источник
3
Ницца! К этому привело удивительное простое событие - сводка пройденных / неудачных / пропущенных тестов.
MarkHu
Я только что интегрировал плагин, но не вижу длительности тестов, как в вашем git для каждого теста в скобках (1.6s). Как это включить?
dk7
@ dk7 по умолчанию только те тесты, которые длятся больше 1 секунды, будут напечатаны. Смотрите документацию для получения дополнительной информации. Если вы хотите увидеть все длительности, просто установите slowThresholdна 0.
adarshr
1
@ HaroldL.Brown Да, действительно :) Я просто немного завален несколькими вещами в настоящее время, но он очень живой.
adarshr
1
Да @ ВадымТемиров. То же, что github.com/radarsh/gradle-test-logger-plugin/issues/137, как только я это задокументирую 🙂
adarshr
49

Добавьте это к, build.gradleчтобы остановить проглочение от проглатывания stdout и stderr.

test {
    testLogging.showStandardStreams = true
}

Это задокументировано здесь .

Дарвин
источник
38

Задача 'test' не работает для плагина Android, для плагина Android используйте следующее:

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

Смотрите следующее: https://stackoverflow.com/a/31665341/3521637

user3521637
источник
3
Потрясающие. К вашему сведению, будущее меня - сэкономьте две минуты, не помещая их в блок Android {}
Шубхам Чаудхари
18

В качестве продолжения великого ответа Шубхэма я хотел бы предложить использовать перечисляемые значения вместо строк . Пожалуйста, ознакомьтесь с документацией класса 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
источник
12

Моя любимая минималистичная версия, основанная на ответе Шубхам Чаудхари. введите описание изображения здесь

Поместите это в build.gradleфайл:

test {
    afterSuite { desc, result ->
    if (!desc.parent)
        println("${result.resultType} " +
            "(${result.testCount} tests, " +
            "${result.successfulTestCount} successes, " +
            "${result.failedTestCount} failures, " +
            "${result.skippedTestCount} skipped)")
    }
}
Анджей Реманн
источник
7

В Gradle с помощью плагина Android:

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

Тогда вывод будет:

Выполнение теста testConversionMinutes [org.example.app.test.DurationTest] с результатом: SUCCESS

radeklos
источник
3

Слияние Shubham Страшного ответа и использование JJD перечисления вместо строки

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
источник
2
Прошу вас добавить немного контекста вокруг вашего ответа. Трудно понять ответы только по коду или по ссылке. Это поможет вам и будущим читателям, если вы сможете добавить больше информации в свой пост.
RBT
2

Следуя ответу Бенджамина Мушко (19 марта 2011 г.), вы можете использовать -iфлаг вместе с grep , чтобы отфильтровать тысячи нежелательных строк. Примеры:

Сильный фильтр - отображать только имя и результат каждого модульного теста, а также общее состояние сборки. Ошибки или исключения при настройке не отображаются.

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

Мягкий фильтр - отображает название и результат каждого модульного теста, а также ошибки / исключения при настройке. Но это также будет включать некоторую не относящуюся к делу информацию:

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

Мягкий фильтр, Альтернативный синтаксис: (токены поиска разбиты на отдельные строки)

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

Объяснение того, как это работает: выходные данные первой команды ./gradlew test -iпередаются второй команде grep, которая отфильтровывает множество нежелательных строк на основе регулярного выражения. "-E"включает режим регулярного выражения и "|"означает «или». Имя модульного теста и его результат разрешено отображать с помощью " > ", а общий статус - с помощью "BUILD". В мягком фильтре "-v"флаг означает «не содержит» и "^"означает «начало строки». Таким образом, он удаляет все строки, которые начинаются с «Выполнение» или начинаются с «Создание» и т. Д.


Пример для тестовых модулей Android с 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:"

Пример покрытия модульным тестом Jacoco с 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
источник
0

Если у вас build.gradle.ktsнаписано на Kotlin DSL, вы можете распечатать результаты теста (я разрабатывал мультиплатформенный проект kotlin, без применения плагина "java"):

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

Просто добавьте следующее закрытие в ваш build.gradle. вывод будет напечатан после выполнения каждого теста.

test{
    useJUnitPlatform()
    afterTest { desc, result ->
        def output = "Class name: ${desc.className}, Test name: ${desc.name},  (Test status: ${result.resultType})"
        println( '\n' + output)
    }
}
Сулеман
источник