Skip to content

Commit

Permalink
Add mergeTestTimes
Browse files Browse the repository at this point in the history
  • Loading branch information
bootstraponline committed Nov 13, 2018
1 parent 5209ead commit 293ef05
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 3 deletions.
12 changes: 10 additions & 2 deletions test_runner/src/main/kotlin/ftl/reports/xml/model/JUnitTestCase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ data class JUnitTestCase(
// JUnit XML allows arbitrary amounts of failure/error tags
@JsonInclude(JsonInclude.Include.NON_NULL)
@JacksonXmlProperty(localName = "failure")
val failures: List<String>?,
val failures: List<String>? = null,

@JsonInclude(JsonInclude.Include.NON_NULL)
@JacksonXmlProperty(localName = "error")
val errors: List<String>?,
val errors: List<String>? = null,

@JsonInclude(JsonInclude.Include.CUSTOM, valueFilter = FilterNotNull::class)
val skipped: String? = "absent" // used by FilterNotNull to filter out absent `skipped` values
Expand All @@ -41,6 +41,14 @@ data class JUnitTestCase(
return failures?.isNotEmpty() == true || errors?.isNotEmpty() == true
}

fun skipped(): Boolean {
return skipped == null
}

fun successful(): Boolean {
return failed().not().and(skipped().not())
}

fun stackTrace(): String {
return failures?.joinToString() + errors?.joinToString()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,18 @@ data class JUnitTestResult(
var testsuites: MutableList<JUnitTestSuite>?
) {
fun mergeTestTimes(other: JUnitTestResult?): JUnitTestResult {
// TODO: ...
if (other == null) return this
if (this.testsuites == null) this.testsuites = mutableListOf()

// newTestResult.mergeTestTimes(oldTestResult)
//
// for each new JUnitTestSuite, check if it exists on old
// if JUnitTestSuite exists on both then merge test times
this.testsuites?.forEach { testSuite ->
val oldSuite = other.testsuites?.firstOrNull { it.name == testSuite.name }
if (oldSuite != null) testSuite.mergeTestTimes(oldSuite)
}

return this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,59 @@ data class JUnitTestSuite(

return this
}

fun mergeTestTimes(other: JUnitTestSuite): JUnitTestSuite {
if (this.name != other.name) throw RuntimeException("Attempted to merge ${other.name} into ${this.name}")

// for each new JUnitTestCase
// iif it failed then pull timing info from old
// remove if not successful in either new or old

// if we ran no test cases then don't bother merging old times.
if (this.testcases == null) return this

val mergedTestCases = mutableListOf<JUnitTestCase>()
var mergedTime = 0.0

this.testcases?.forEach { testcase ->
// if test was skipped, then continue to skip it.
if (testcase.skipped()) return@forEach

// if the test succeeded, use the new time value
if (testcase.successful()) {
mergedTime += testcase.time.toDouble()
mergedTestCases.add(
JUnitTestCase(
name = testcase.name,
classname = testcase.classname,
time = testcase.time
)
)
return@forEach
}

// if the test we ran failed, copy timing from the last successful run
val lastSuccessfulRun = other.testcases?.firstOrNull {
it.successful() && it.name == testcase.name && it.classname == testcase.classname
} ?: return@forEach

mergedTime += lastSuccessfulRun.time.toDouble()
mergedTestCases.add(
JUnitTestCase(
name = testcase.name,
classname = testcase.classname,
time = lastSuccessfulRun.time
)
)
}

this.testcases = mergedTestCases
this.tests = mergedTestCases.size.toString()
this.failures = "0"
this.errors = "0"
this.skipped = "0"
this.time = mergedTime.toString()

return this
}
}
51 changes: 51 additions & 0 deletions test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -312,4 +312,55 @@ junit.framework.Assert.fail(Assert.java:50)</failure>
}
}
}

@Test
fun merge_testTimes() {
val newRun = """
<?xml version='1.0' encoding='UTF-8' ?>
<testsuites>
<testsuite name="EarlGreyExampleSwiftTests" tests="4" failures="1" errors="0" skipped="0" time="51.773" hostname="localhost">
<testcase name="a()" classname="a" time="1.0"/>
<testcase name="b()" classname="b" time="2.0"/>
<testcase name="c()" classname="c" time="0.584">
<failure>Exception: NoMatchingElementException</failure>
<failure>failed: caught "EarlGreyInternalTestInterruptException", "Immediately halt execution of testcase"</failure>
</testcase>
<testcase name="d()" classname="d" time="0.0">
<skipped/>
</testcase>
</testsuite>
</testsuites>
""".trimIndent()

val oldRun = """
<?xml version='1.0' encoding='UTF-8' ?>
<testsuites>
<testsuite name="EarlGreyExampleSwiftTests" tests="4" failures="1" errors="0" skipped="0" time="51.773" hostname="localhost">
<testcase name="a()" classname="a" time="5.0"/>
<testcase name="b()" classname="b" time="6.0"/>
<testcase name="c()" classname="c" time="7.0"/>
<testcase name="d()" classname="d" time="8.0"/>
</testsuite>
</testsuites>
""".trimIndent()

// new run has 2 passing, 1 failure, and 1 skipped
// * a() and b() passed in newRun and are copied over
// * c() failed in newRun and passed in oldRun. timing info copied over from oldRun
// * d() was skipped in newRun and successful in oldRun. d() is excluded from the merged result

val merged = parseIosXml(newRun).mergeTestTimes(parseIosXml(oldRun)).xmlToString()
val expected = """
<?xml version='1.0' encoding='UTF-8' ?>
<testsuites>
<testsuite name="EarlGreyExampleSwiftTests" tests="3" failures="0" errors="0" skipped="0" time="10.0" hostname="localhost">
<testcase name="a()" classname="a" time="1.0"/>
<testcase name="b()" classname="b" time="2.0"/>
<testcase name="c()" classname="c" time="7.0"/>
</testsuite>
</testsuites>
""".trimIndent()
assertThat(merged).isEqualTo(expected)
}
}

0 comments on commit 293ef05

Please sign in to comment.