如何让Gradle在某些控制台输出上测试失败

如何让Gradle在某些控制台输出上测试失败,gradle,Gradle,我试图将Gradle配置为在检测到特定控制台输出时使测试失败,但前提是该测试尚未失败 为了更好地理解上下文,每当控制台上记录单词“LEAK”时,我都试图让测试失败,Netty会这样做 我当前的解决方案如下所示: ext { testsWithLeak = [:] } test { useJUnitPlatform() onOutput { test, output -> if (output.message.contains("LEAK")) {

我试图将Gradle配置为在检测到特定控制台输出时使测试失败,但前提是该测试尚未失败

为了更好地理解上下文,每当控制台上记录单词
“LEAK”
时,我都试图让测试失败,Netty会这样做

我当前的解决方案如下所示:

ext {
    testsWithLeak = [:]
}

test {
    useJUnitPlatform()

    onOutput { test, output ->
        if (output.message.contains("LEAK")) {
            testsWithLeak[test] = output.message
        }
    }

    afterTest { test, result ->
        if (result.getResultType().equals(TestResult.ResultType.FAILURE)) {
            testsWithLeak.remove(test);
        }
    }

    finalizedBy 'checkLeaks'
}

task checkLeaks {
    dependsOn 'test'
    doLast {
        testsWithLeak.each{entry ->
            throw new GradleException("ERROR: $entry.key produced leak: $entry.value")
        }
    }
}
这主要起作用,并且在检测到
泄漏消息时,将正确地使构建失败。问题在于,由于测试本身被认为是成功的,它似乎被缓存了,并且在后续构建中不会再次运行。我尝试调用
cleanTest
,作为抛出
GradleException
的一部分,但这没有帮助

请注意,我使用了
testsWithLeak
变量,因为我只想在测试尚未失败时引发此异常。测试可能会由于其他断言而失败,在这种情况下,我不想检查是否存在泄漏(因为
GradleException
可能会掩盖潜在的断言失败)

还请注意,将
GradleException
作为
postertest
闭包的一部分抛出似乎不会使构建失败

我怎样才能:

  • 当测试记录此消息时,生成失败
  • 只有当测试没有失败时才抛出此异常
  • 确保生成在后续尝试中正确失败(不依赖命令行选项)

  • 测试被认为是最新的,因为测试输入(类文件)和测试输出(xml报告)自上次运行以来没有更改。您可以执行以下操作,以便测试永远不会是最新的

    test {
       outputs.upToDateWhen {false}
       ... 
    } 
    


    您的
    testsWithLeak
    映射将不会在gradle调用之间保持。我建议您在
    $buildDir
    下写入一个文件,并在{…}
    谓词时添加一个
    TaskOutputs.uptdate以检查该文件是否存在。您的
    checkLeaks
    任务也应该由文件驱动,而不是由项目变量驱动

    例如:


    感谢您的回复,但我不想一直使测试缓存无效——只有在构建因此原因失败时才如此。是否有一种方法可以将它们标记为不是此故障序列的最新部分?例如,我想使用类似
    doNotCacheIf的东西​
    ,但我不确定如何使用我的
    Finalized by
    逻辑。您可以在测试任务的
    doLast{…}
    块中抛出异常,而不是在测试任务中使用单独的任务
    doLast{…}
    ,谢谢!有趣的是,在
    doLast{…}
    中抛出异常,而不是
    postertest{…}
    ,将更改生成结果。我不一定希望映射在调用之间保持不变,我只想确保在后续尝试中重新运行测试。如果可能的话,我更愿意在不接触文件系统的情况下执行此操作。您所说的“后续尝试”显然是后续的Gradle调用。正如我所说的,如果您想在调用之间保持状态,那么它是通过文件系统完成的。或者,任务可能会失败(最终通过Gradle内部缓存中的文件系统记录)
    test {
       ext {
          testsWithLeak = new java.util.Properties() 
          leakFile = file("$buildDir/testsWithLeak.props")
       } 
       outputs.upToDateWhen {!leakFile.exists()}
       onOutput {...}
       afterTest {...}
       doFirst {
          delete leakFile
       } 
       doLast {
          if (testsWithLeak) {
             leakFile.withWriter { testsWithLeak.store(it)}
          } 
       } 
    }