如何使用Gradle仅重新运行失败的JUnit测试类?相关实现疑问
Great question! Let's break this down into two parts: a simpler Gradle implementation for rerunning failed JUnit tests, and how to get a consolidated list of failed tests.
Option 1: Use Gradle's Built-in Test Retry (Automatic Retries)
If you want failed tests to automatically retry during the test run, Gradle has built-in support starting from version 4.6. This is the most straightforward approach—no need to manually create extra tasks:
test { retry { maxRetries = 2 // Number of times to retry each failed test maxFailures = 5 // Stop execution if more than 5 tests fail (optional) retryOnFailure = true // Only retry tests that actually failed } }
This configures your test task to automatically retry failed cases right after they fail, which works seamlessly for most use cases.
Option 2: Simplified Manual Rerun Tasks
If you need to manually trigger a rerun of only the failed tests (instead of automatic retries), you can automate the creation of Rerun tasks for all your Test-type tasks with a single script block. This avoids the hassle of defining each task individually:
tasks.withType(Test) { testTask -> tasks.register("${testTask.name}Rerun", Test) { // Reuse the original task's classpath and test classes testClassesDirs = testTask.testClassesDirs classpath = testTask.classpath // Extract failed tests from previous test result XML files def failedTests = [] def resultsDir = testTask.testResultsDir if (resultsDir.exists()) { resultsDir.eachFileMatch(~/.*\.xml/) { xmlFile -> def testResults = new XmlSlurper().parse(xmlFile) testResults.testcase.each { testcase -> if (testcase.failure || testcase.error) { failedTests.add("${testcase.@classname}.${testcase.@name}") } } } } if (!failedTests.isEmpty()) { includeTestsMatching failedTests.join(',') } else { doLast { println "No failed tests to rerun for ${testTask.name}!" } } } }
Run ./gradlew testRerun (or integrationTestRerun for your integration test tasks) to execute only the tests that failed in the previous run.
To get a merged list of all failed tests across all your test tasks, create a custom Gradle task that collects results from all test reports:
tasks.register("consolidateFailedTests") { dependsOn tasks.withType(Test) // Ensure all test tasks complete first doLast { def allFailedTests = [] tasks.withType(Test).each { testTask -> def resultsDir = testTask.testResultsDir if (resultsDir.exists()) { resultsDir.eachFileMatch(~/.*\.xml/) { xmlFile -> def testResults = new XmlSlurper().parse(xmlFile) testResults.testcase.each { testcase -> if (testcase.failure || testcase.error) { allFailedTests.add("${testTask.name}: ${testcase.@classname}.${testcase.@name}") } } } } } if (allFailedTests.isEmpty()) { println "✅ All tests passed! No failures to report." } else { println "\n❌ Consolidated Failed Tests:" allFailedTests.each { println "- $it" } // Optional: Save the list to a file for later reference file("failed-tests-summary.txt").text = allFailedTests.join('\n') } } }
Run ./gradlew consolidateFailedTests to see a unified list of failed tests in your console, plus a failed-tests-summary.txt file with the same content.
内容的提问来源于stack exchange,提问作者Tom Tresansky

