diff --git a/src/main/groovy/com/ullink/gradle/nunit/NUnit.groovy b/src/main/groovy/com/ullink/gradle/nunit/NUnit.groovy index a2dc954..3ebee41 100644 --- a/src/main/groovy/com/ullink/gradle/nunit/NUnit.groovy +++ b/src/main/groovy/com/ullink/gradle/nunit/NUnit.groovy @@ -37,6 +37,7 @@ class NUnit extends ConventionTask { def logFile boolean ignoreFailures = false boolean parallelForks = true + boolean adjustTestResults = false def test = Wrapper.newInstance() def where = Wrapper.newInstance() @@ -299,7 +300,7 @@ class NUnit extends ConventionTask { if (env) environment env commandLine = commandLineExec - ignoreExitValue = ignoreFailures + ignoreExitValue = true } int exitValue = mbr.exitValue @@ -307,12 +308,15 @@ class NUnit extends ConventionTask { return } - boolean anyTestFailing = exitValue > 0 - if (anyTestFailing && ignoreFailures) { + if (exitValue > 0) { + //failed tests but no error + if (!ignoreFailures) { + throw new GradleException("There are failing tests (exitCode = ${mbr.exitValue})") + } return } - throw new GradleException("${getNunitExec()} execution failed (ret=${mbr.exitValue})"); + throw new GradleException("${getNunitExec()} execution failed (exitCode =${mbr.exitValue})") } def prepareExecute() { diff --git a/src/main/groovy/com/ullink/gradle/nunit/NUnitPlugin.groovy b/src/main/groovy/com/ullink/gradle/nunit/NUnitPlugin.groovy index fe5b393..1cee412 100644 --- a/src/main/groovy/com/ullink/gradle/nunit/NUnitPlugin.groovy +++ b/src/main/groovy/com/ullink/gradle/nunit/NUnitPlugin.groovy @@ -1,5 +1,6 @@ package com.ullink.gradle.nunit +import com.ullink.gradle.nunit.adjuster.NunitTestResultAdjuster import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task @@ -10,5 +11,8 @@ class NUnitPlugin implements Plugin { Task defaultNUnitTask = project.task('nunit', type: NUnit) defaultNUnitTask.description = 'Executes NUnit tests' + + Task resultsAdjuster = project.task('nunitTestResultAdjuster', type: NunitTestResultAdjuster) + defaultNUnitTask.finalizedBy(resultsAdjuster) } } diff --git a/src/main/groovy/com/ullink/gradle/nunit/adjuster/Nunit2Adjuster.groovy b/src/main/groovy/com/ullink/gradle/nunit/adjuster/Nunit2Adjuster.groovy new file mode 100644 index 0000000..e2cc7c9 --- /dev/null +++ b/src/main/groovy/com/ullink/gradle/nunit/adjuster/Nunit2Adjuster.groovy @@ -0,0 +1,78 @@ +package com.ullink.gradle.nunit.adjuster + +import groovy.xml.XmlUtil +import org.slf4j.Logger + +class Nunit2Adjuster { + + static void UpdateReportFileForNunit2(File testResultsFile, Logger logger) { + logger.info("Checking if adjustments on the test results for Nunit 2 are needed.") + + def xmlFile = new XmlParser().parse(testResultsFile) + + if (!isNumberOfFailedTestsConsistentWithOverallResult(xmlFile)) { + logger.info("The overall result of the Test Results is not consistent with the number of failed tests. Adjusting test results...") + + AppendFailingTestCase(xmlFile) + + testResultsFile.write(XmlUtil.serialize(xmlFile)) + } else { + logger.info("The overall result of the Test Results is consistent with the number of failed tests so no adjusting needed.") + } + } + + private static void AppendFailingTestCase(Node xmlFile) { + def failingTestToAppend = new XmlParser(false, true).parseText(getFailingTestCase()) + + def resultsXmlNode = xmlFile.children() + .find { it.name() == "test-suite" } + .find { it.name() == 'results' } + .children() + + resultsXmlNode.add(resultsXmlNode.size(), failingTestToAppend) + } + + private static boolean isNumberOfFailedTestsConsistentWithOverallResult(Node xmlFile) { + if (isOverallResultFailed(xmlFile)) { + def numberOfFailedTests = xmlFile.attributes().find { it.key == "failures" }.value + if (numberOfFailedTests == "0") + return false + return true + } + return true + } + + private static boolean isOverallResultFailed(Node xmlFile){ + boolean isFailedResult = false + + def rootNodeForTests = xmlFile.children().find {it.name() == "test-suite"} + def assemblyType = rootNodeForTests.attributes().find {it.key=="type"} + if (assemblyType.value == "Assembly") + { + def resultForAssembly = rootNodeForTests.attributes().find {it.key == "result"} + if (resultForAssembly.value == "Failure") { + isFailedResult = true + } + } + return isFailedResult + } + + private static String getFailingTestCase() + { + return ''' + + + + + + + + + + + + + + ''' + } +} diff --git a/src/main/groovy/com/ullink/gradle/nunit/adjuster/Nunit3Adjuster.groovy b/src/main/groovy/com/ullink/gradle/nunit/adjuster/Nunit3Adjuster.groovy new file mode 100644 index 0000000..afa10f3 --- /dev/null +++ b/src/main/groovy/com/ullink/gradle/nunit/adjuster/Nunit3Adjuster.groovy @@ -0,0 +1,59 @@ +package com.ullink.gradle.nunit.adjuster + +import groovy.xml.XmlUtil +import org.slf4j.Logger + +class Nunit3Adjuster { + + static void UpdateReportFileForNunit3(File testResultsFile, Logger logger) { + logger.info("Checking if adjustments on the test results for Nunit 3 are needed.") + + def xmlFile = new XmlParser().parse(testResultsFile) + + if (!isNumberOfFailedTestsConsistentWithOverallResult(xmlFile)) { + logger.info("The overall result of the Test Results is not consistent with the number of failed tests. Adjusting test results...") + + AppendFailingTestCase(xmlFile) + + testResultsFile.write(XmlUtil.serialize(xmlFile)) + } else { + logger.info("The overall result of the Test Results is consistent with the number of failed tests so no adjusting needed.") + } + } + + private static void AppendFailingTestCase(Node xmlFile) { + def failingTestToAppend = new XmlParser(false, true).parseText(getFailingTestCase()) + def xmlNodeChildren = xmlFile.find { it.name() == 'test-suite' }.children() + xmlNodeChildren.add(xmlNodeChildren.size(), failingTestToAppend) + } + + private static boolean isNumberOfFailedTestsConsistentWithOverallResult(Node xmlFile) { + if (isOverallResultFailed(xmlFile)) { + def numberOfFailedTests = xmlFile.attributes().find { it.key == "failed" }.value + if (numberOfFailedTests == "0") + return false + return true + } + return true + } + + private static boolean isOverallResultFailed(Node xmlFile) { + return xmlFile.attributes().find { it.key == "result" }.value == "Failed" + } + + private static String getFailingTestCase() { + return ''' + + + + + + Appended failing test + + + + + + ''' + } +} diff --git a/src/main/groovy/com/ullink/gradle/nunit/adjuster/NunitTestResultAdjuster.groovy b/src/main/groovy/com/ullink/gradle/nunit/adjuster/NunitTestResultAdjuster.groovy new file mode 100644 index 0000000..76a1075 --- /dev/null +++ b/src/main/groovy/com/ullink/gradle/nunit/adjuster/NunitTestResultAdjuster.groovy @@ -0,0 +1,29 @@ +package com.ullink.gradle.nunit.adjuster + +import com.ullink.gradle.nunit.NUnit +import org.gradle.api.tasks.Exec + +class NunitTestResultAdjuster extends Exec { + + @Override + protected void exec() { + NUnit nunitTask = project.tasks.nunit + File testReportPath = nunitTask.getTestReportPath() + + if (!nunitTask.adjustTestResults) { + project.logger.info("No adjustments on the generated tests results will be made.") + return + } + + if (isTestResultFormatInNunit3(nunitTask)) { + Nunit3Adjuster.UpdateReportFileForNunit3(testReportPath, project.logger) + } else { + Nunit2Adjuster.UpdateReportFileForNunit2(testReportPath, project.logger) + } + } + + private boolean isTestResultFormatInNunit3(NUnit nUnit) { + def nunitResultFormat = nUnit.resultFormat + return nunitResultFormat == null || nunitResultFormat != 'nunit2' + } +}