Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust NUnit test results #56

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/main/groovy/com/ullink/gradle/nunit/NUnit.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -299,20 +300,23 @@ class NUnit extends ConventionTask {
if (env)
environment env
commandLine = commandLineExec
ignoreExitValue = ignoreFailures
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why hardcode the setting instead of using the argument?

ignoreExitValue = true
}

int exitValue = mbr.exitValue
if (exitValue == 0) {
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exitValue != 0 ?

}

throw new GradleException("${getNunitExec()} execution failed (ret=${mbr.exitValue})");
throw new GradleException("${getNunitExec()} execution failed (exitCode =${mbr.exitValue})")
}

def prepareExecute() {
Expand Down
4 changes: 4 additions & 0 deletions src/main/groovy/com/ullink/gradle/nunit/NUnitPlugin.groovy
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -10,5 +11,8 @@ class NUnitPlugin implements Plugin<Project> {

Task defaultNUnitTask = project.task('nunit', type: NUnit)
defaultNUnitTask.description = 'Executes NUnit tests'

Task resultsAdjuster = project.task('nunitTestResultAdjuster', type: NunitTestResultAdjuster)
defaultNUnitTask.finalizedBy(resultsAdjuster)
}
}
Original file line number Diff line number Diff line change
@@ -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...")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warn?


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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what is this

{
return '''
<test-suite type="TestSuite" name="FailingTest" executed="True" result="Failure" success="False" time="0.091" asserts="2">
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
<stack-trace />
</failure>
<results>
<test-case name="FailingTestDueToFailingTestResult" executed="True" result="Failure" success="False" time="0.077" asserts="1">
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
</test-case>
</results>
</test-suite>
'''
}
}
Original file line number Diff line number Diff line change
@@ -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 '''
<test-suite type="TestSuite" id="9999-9996" name="Ullink" fullname="Ullink.Test" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2019-05-06 07:10:49Z" end-time="2019-05-06 07:10:49Z" duration="0.100747" total="1" passed="0" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="1">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the harcoded values could cause issues, like id, start-time etc.

<test-suite type="TestSuite" id="9999-9997" name="Test" fullname="Ullink.Test" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2019-05-06 07:10:49Z" end-time="2019-05-06 07:10:49Z" duration="0.100737" total="1" passed="0" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="1">
<test-suite type="TestFixture" id="9999-9998" name="FailingFixture" fullname="Ullink.Test.FailingFixture" classname="Ullink.Test.FailingFixture" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2019-05-06 07:10:49Z" end-time="2019-05-06 07:10:49Z" duration="0.067676" total="1" passed="0" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="1">
<test-case id="9999-9999" name="FailingTest" fullname="Ullink.Test.FailingFixture.FailingTest" methodname="FailingTest" classname="Ullink.Test.FailingFixture" runstate="Runnable" seed="420273222" result="Failed" start-time="2019-05-06 07:10:49Z" end-time="2019-05-06 07:10:49Z" duration="0.067506" asserts="1">
<failure>
<message> Appended failing test</message>
</failure>
</test-case>
</test-suite>
</test-suite>
</test-suite>
'''
}
}
Original file line number Diff line number Diff line change
@@ -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'
}
}