Gradle:如何实时在控制台中显示测试结果?

337

我希望能够在同一控制台中实时查看测试结果(包括system.out / err、被测试组件的日志消息)

gradle test

在测试完成后生成的测试报告中查看测试结果是不够及时的,因为在测试运行期间无法实时查看报告。


1
请参考以下链接 https://stackoverflow.com/questions/45856846/how-can-i-share-build-code-script-for-all-my-gradle-projects-not-just-subprojec ,了解如何通过初始化脚本添加测试输出,以便任何项目都可以免费获取它。 - Pat
对于UI androidTests,这些方法都对我无效。它似乎只显示跳过的测试,无法继续进行。 - undefined
19个回答

250

这是我的华丽版本:

fancy test result

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

17
在我看来,这是这里最好的答案。它包含了最大的选项集合,每个人都可以根据自己的需要配置他们的测试。 - Slav
6
请问这段代码需要复制到哪里,并且如何在命令行中运行?编辑:我明白了-只需将其添加到模块的gradle.config文件中,然后按照正常流程运行即可。 - hardysim
1
你是如何启用颜色的? - Durga Swaroop
1
@DurgaSwaroop 对我来说直接使用就可以了。请确保您的终端应用程序支持颜色。我个人使用iTerm2应用程序。 - Shubham Chaudhary
1
与Gradle 4.5完美兼容,运行良好。 - Peter
显示剩余8条评论

244

你可以在命令行上以INFO日志级别运行Gradle。这样它会显示每个测试运行时的结果。缺点是你也会得到其他任务的远多于正常输出。

gradle test -i

18
从1.0-milestone 6版本开始,Gradle DSL现在可以在test闭包中直接使用[testLogging.showStandardStreams = true](http://forums.gradle.org/gradle/topics/seeing_test_output_at_the_console)进行配置。您可以使用此功能来查看测试输出结果。 - Benjamin Muschko
4
在Gradle 1.11中这并不起作用。我得到了很多调试输出,但没有得到单个测试结果。 - David Moles
75
那个 -i 会在终端上输出一堆无关的信息。 - Thuy Trinh
15
除了大量无用的输出外,对于通过并生成无输出的测试,没有显示任何内容。 - user23987
2
你可以使用 grep 过滤掉成千上万不需要的行。请参阅 https://dev59.com/sW865IYBdhLWcg3wIrFg#52904915。 - Mr-IDE
显示剩余2条评论

228

免责声明:我是Gradle Test Logger插件的开发者。

您可以使用Gradle Test Logger插件在控制台上打印漂亮的日志。该插件使用明智的默认设置,以满足大多数用户的需求,并提供许多主题和配置选项来适应各种需求。

示例

标准主题 标准主题

Mocha主题 Mocha主题

用法

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
}

我希望你会喜欢使用它。


7
太好了!令人惊讶的是,一个简单的已通过/未通过/跳过测试摘要就导致了这种结果。 - MarkHu
1
我刚刚集成了插件,但是我没有看到测试持续时间,就像你的git中每个测试括号中所示(1.6秒)。如何启用它? - dk7
2
@HaroldL.Brown 是的,确实如此 :) 我现在有一些事情要忙,但它仍然非常活跃。 - adarshr
1
是的 @VadymTyemirov。和 https://github.com/radarsh/gradle-test-logger-plugin/issues/137 一样,一旦我记录下来,就一样了。 - adarshr
2
对于多模块项目,请在根目录的build.gradle中添加以下内容:plugins { id 'com.adarshr.test-logger' version '2.1.0' } subprojects { apply plugin: 'com.adarshr.test-logger' } - tonisives
显示剩余9条评论

179
你可以在build.gradle文件中添加一个Groovy闭包来进行日志记录:

您可以在build.gradle文件中添加一个Groovy闭包,以便为您进行日志记录:

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

6
仅在测试执行后,才会生成输出结果。我希望能够实时查看日志/报告/系统输出/println等内容,即在测试运行时看到输出结果。考虑使用Maven执行测试或在IntelliJ / Eclipse中运行测试:输出结果会实时生成。 - tolitius
好的,抱歉误解了你的问题。针对这种情况,您应该查看Gradle文档的以下部分:http://gradle.org/logging.html#sec:external_tools - stefanglase
2
那么我需要做哪些更改才能看到输出呢?我在文档中看到了所有这些自定义监听器之类的东西,但我不知道如何配置它们。 - jpswain
@stefanglase的评论更新链接:https://docs.gradle.org/current/userguide/logging.html#sec:external_tools - Starwarswii

154

正如stefanglase所回答的:

将以下代码添加到您的build.gradle文件中(自版本1.1起),可以很好地输出已通过跳过失败的测试结果。

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

另外我想要补充的一点是(我发现这对新手来说是个问题),gradle test 命令每次只会对更改后的测试执行一次

所以,如果你第二次运行它,就不会有测试结果输出了。你也可以在构建输出中看到这一点:gradle 就会在测试上说UP-TO-DATE,因此没有被执行第 n 次。

聪明的 gradle!

如果你想强制运行测试用例,请使用 gradle cleanTest test 命令。

虽然略微偏题,但我希望这能帮助一些新手。

编辑

正如sparc_spread在评论中提到的:

如果你想让 gradle 总是运行新的测试(这可能并不总是一个好主意),你可以在 testLogging { [...] } 中添加 outputs.upToDateWhen {false}。继续阅读这里

和平。


12
嗨,只是想让你知道(在Gradle 1.12及以后版本中),我找到了一种不必每次都输入 gradle cleanTest test的方法。将 outputs.upToDateWhen {false} 添加到 testLogging {...} 中即可。这将强制Gradle每次运行测试。我发现这个方法在Gradle论坛上由Dockter本人发布。希望对你有所帮助。 - sparc_spread
1
我会包含exceptionFormat "full"以获取有关失败细节的信息,在使用AssertJ或类似库时非常有用。 - Shairon Toledo
5
可以使用test --rerun-tasks替代cleanTest - gavenkoa
2
@gavenkoa 我认为 --rerun-tasks 会重新运行所有任务,而不仅仅是测试任务。 - ThomasW
2
实际上,在最新的Android Studio和gradle 3.3上,我的一侧无法正常运行cleanTest test,但是--rerun-tasks解决了问题。不知道为什么。但是阅读这个答案真的解决了我的头痛问题,我添加所有内容后在哪里可以找到测试日志。 - Wingzero
这个很好用,但是当我使用-i标志来获取更多信息时,它就不再工作了。有什么想法为什么? - john k

70
将以下内容添加到build.gradle中,以防止gradle吞噬标准输出和错误输出。
test {
    testLogging.showStandardStreams = true
}

相关文档在这里


3
对于任何 Kotlin 开发者来说,这段代码应该是 val test by tasks.getting(Test::class) { testLogging.showStandardStreams = true } - Brad Turek
FYI @langusten-gustel 提出的 "...所以如果你第二次运行它,测试结果将没有输出" 问题仍然存在。 - sming

47

'test' 任务在 Android 插件中无法使用,请改用以下内容:

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

请参见以下链接:https://dev59.com/1Izda4cB1Zd3GeqPqsOK#31665341


5
很棒。FYI 未来的我 - 不要把它放在 android{} 块内,这样可以节省你两分钟的时间。 - Shubham Chaudhary

25
作为Shubham's great answer的后续,我建议使用枚举值代替字符串。请查看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
    }
}

20

我最喜欢的极简版本是基于Shubham Chaudhary的答案。 在此输入图像描述

将此放入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

在使用 Android 插件的 Gradle 中:

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],结果为:成功


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接