gpt4 book ai didi

gradle - 如何使用 Gradle 重新运行失败的 JUnit 测试类?

转载 作者:行者123 更新时间:2023-12-02 07:22:31 25 4
gpt4 key购买 nike

灵感来自this neat TestNG task ,和this SO question我想我应该快速从 Gradle 中重新运行失败的 JUnit 测试。

但是在搜索了一段时间后,我找不到任何类似的东西,而且非常方便。

我想出了以下内容,它似乎工作得很好,并添加了 <testTaskName>Rerun每个任务类型 Test 的任务在我的项目中。

import static groovy.io.FileType.FILES

import java.nio.file.Files
import java.nio.file.Paths

// And add a task for each test task to rerun just the failing tests
subprojects {
afterEvaluate { subproject ->
// Need to store tasks in static temp collection, else new tasks will be picked up by live collection leading to StackOverflow
def testTasks = subproject.tasks.withType(Test)
testTasks.each { testTask ->
task "${testTask.name}Rerun"(type: Test) {
group = 'Verification'
description = "Re-run ONLY the failing tests from the previous run of ${testTask.name}."

// Depend on anything the existing test task depended on
dependsOn testTask.dependsOn

// Copy runtime setup from existing test task
testClassesDirs = testTask.testClassesDirs
classpath = testTask.classpath

// Check the output directory for failing tests
File textXMLDir = subproject.file(testTask.reports.junitXml.destination)
logger.info("Scanning: $textXMLDir for failed tests.")

// Find all failed classes
Set<String> allFailedClasses = [] as Set
if (textXMLDir.exists()) {
textXMLDir.eachFileRecurse(FILES) { f ->
// See: http://marxsoftware.blogspot.com/2015/02/determining-file-types-in-java.html
String fileType
try {
fileType = Files.probeContentType(f.toPath())
} catch (IOException e) {
logger.debug("Exception when probing content type of: $f.")
logger.debug(e)

// Couldn't determine this to be an XML file. That's fine, skip this one.
return
}

logger.debug("Filetype of: $f is $fileType.")

if (['text/xml', 'application/xml'].contains(fileType)) {
logger.debug("Found testsuite file: $f.")

def testSuite = new XmlSlurper().parse(f)
def failedTestCases = testSuite.testcase.findAll { testCase ->
testCase.children().find { it.name() == 'failure' }
}

if (!failedTestCases.isEmpty()) {
logger.info("Found failures in file: $f.")
failedTestCases.each { failedTestCase ->
def className = failedTestCase['@classname']
logger.info("Failure: $className")
allFailedClasses << className.toString()
}
}
}
}
}

if (!allFailedClasses.isEmpty()) {
// Re-run all tests in any class with any failures
allFailedClasses.each { c ->
def testPath = c.replaceAll('\\.', '/') + '.class'
include testPath
}

doFirst {
logger.warn('Re-running the following tests:')
allFailedClasses.each { c ->
logger.warn(c)
}
}
}

outputs.upToDateWhen { false } // Always attempt to re-run failing tests
// Only re-run if there were any failing tests, else just print warning
onlyIf {
def shouldRun = !allFailedClasses.isEmpty()
if (!shouldRun) {
logger.warn("No failed tests found for previous run of task: ${subproject.path}:${testTask.name}.")
}

return shouldRun
}
}
}
}
}

有没有更简单的方法可以从 Gradle 做到这一点?有没有办法让 JUnit 以某种方式输出故障的综合列表,这样我就不必吞咽 XML 报告?

我正在使用 JUnit 4.12 和 Gradle 4.5。

最佳答案

这是一种方法。完整文件将列在最后,并且可以使用 here .

第一个部分是为每个失败的测试编写一个小文件(称为failures):

test {
// `failures` is defined elsewhere, see below
afterTest { desc, result ->
if ("FAILURE" == result.resultType as String) {
failures.withWriterAppend {
it.write("${desc.className},${desc.name}\n")
}
}
}
}

在第二部分中,我们使用测试过滤器(文档 here )将测试限制为 failures 文件中存在的任何测试:

def failures = new File("${projectDir}/failures.log")
def failedTests = []
if (failures.exists()) {
failures.eachLine { line ->
def tokens = line.split(",")
failedTests << tokens[0]
}
}
failures.delete()

test {
filter {
failedTests.each {
includeTestsMatching "${it}"
}
}
// ...
}

完整文件是:

apply plugin: 'java'

repositories {
jcenter()
}

dependencies {
testCompile('junit:junit:4.12')
}

def failures = new File("${projectDir}/failures.log")
def failedTests = []
if (failures.exists()) {
failures.eachLine { line ->
def tokens = line.split(",")
failedTests << tokens[0]
}
}
failures.delete()

test {
filter {
failedTests.each {
includeTestsMatching "${it}"
}
}

afterTest { desc, result ->
if ("FAILURE" == result.resultType as String) {
failures.withWriterAppend {
it.write("${desc.className},${desc.name}\n")
}
}
}
}

关于gradle - 如何使用 Gradle 重新运行失败的 JUnit 测试类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48815890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com