mirror of https://github.com/sbt/sbt.git
Fix for JUnitXmlTestsListener that is removing part of test name when it contains dot (#5139)
Fix for JUnitXmlTestsListener removing part of test when it contains dot Fixes https://github.com/sbt/sbt/issues/5114 Fixes https://github.com/sbt/sbt/issues/2949
This commit is contained in:
parent
0bdde4aee8
commit
108611ca25
|
|
@ -26,7 +26,16 @@ lazy val root = (project in file(".")).
|
|||
if( oneSecondReport.label != "testsuite" ) sys.error("Report should have a root <testsuite> element.")
|
||||
// somehow the 'success' event doesn't go through... TODO investigate
|
||||
// if( (oneSecondReport \ "@time").text.toFloat < 1f ) sys.error("expected test to take at least 1 sec")
|
||||
if( (oneSecondReport \ "@tests").text != "1" ) sys.error("expected 1 tests")
|
||||
if( (oneSecondReport \ "@failures").text != "0" ) sys.error("expected 0 failures")
|
||||
if( (oneSecondReport \ "@name").text != "a.pkg.OneSecondTest" ) sys.error("wrong fixture name: " + (oneSecondReport \ "@name").text)
|
||||
oneSecondReport foreach { testsuite =>
|
||||
val className = testsuite \ "testcase" \@ "classname"
|
||||
if( className != "a.pkg.OneSecondTest" ) sys.error(s"wrong class name: $className")
|
||||
|
||||
val actualTestName = testsuite \ "testcase" \@ "name"
|
||||
if( actualTestName != "oneSecond") sys.error(s"wrong test names: $actualTestName")
|
||||
}
|
||||
// TODO more checks
|
||||
|
||||
val failingReport = XML.loadFile(failingReportFile)
|
||||
|
|
@ -37,17 +46,36 @@ lazy val root = (project in file(".")).
|
|||
|
||||
val scalaTestFlatReport = XML.loadFile(flatSuiteReportFile)
|
||||
if( scalaTestFlatReport.label != "testsuite" ) sys.error("Report should have a root <testsuite> element.")
|
||||
if( (scalaTestFlatReport \ "@tests").text != "2" ) sys.error("expected 2 tests")
|
||||
if( (scalaTestFlatReport \ "@tests").text != "3" ) sys.error("expected 3 tests")
|
||||
if( (scalaTestFlatReport \ "@failures").text != "1" ) sys.error("expected 1 failures")
|
||||
if( (scalaTestFlatReport \ "@name").text != "my.scalatest.MyFlatSuite" ) sys.error("wrong fixture name: " + (scalaTestFlatReport \ "@name").text)
|
||||
scalaTestFlatReport foreach { testsuite =>
|
||||
val classNames = (testsuite \ "testcase").map(_ \@ "classname")
|
||||
if( classNames.length != 3 ) sys.error(s"expected 3 classname's, actual result: " + classNames.length)
|
||||
if( classNames.toSet != Set("my.scalatest.MyFlatSuite") ) sys.error(s"wrong class names: ${classNames.mkString(", ")}")
|
||||
|
||||
val expectedTestNames = Set(
|
||||
"Passing test should pass",
|
||||
"Passing test should also pass with file.extension",
|
||||
"Failing test should fail"
|
||||
)
|
||||
val actualTestName = (testsuite \ "testcase").map(_ \@ "name")
|
||||
if( actualTestName.toSet != expectedTestNames) sys.error(s"wrong test names: ${actualTestName.mkString(", ")}")
|
||||
}
|
||||
|
||||
val nestedSuitesReport = XML.loadFile(nestedSuitesReportFile)
|
||||
if( nestedSuitesReport.label != "testsuite" ) sys.error("Report should have a root <testsuite> element.")
|
||||
if( (nestedSuitesReport \ "@tests").text != "2" ) sys.error("expected 2 tests")
|
||||
if( (nestedSuitesReport \ "@failures").text != "1" ) sys.error("expected 1 failures")
|
||||
if( (nestedSuitesReport \ "@name").text != "my.scalatest.MyNestedSuites" ) sys.error("wrong fixture name: " + (nestedSuitesReport \ "@name").text)
|
||||
val actualTestName = (nestedSuitesReport \ "testcase").map(t => (t \ "@name").text)
|
||||
if( actualTestName.toSet != Set("MyInnerSuite.Inner passing test should pass", "MyInnerSuite.Inner failing test should fail")) sys.error(s"wrong test names: ${actualTestName.mkString(", ")}")
|
||||
nestedSuitesReport foreach { testsuite =>
|
||||
val classNames = (testsuite \ "testcase").map(_ \@ "classname")
|
||||
if( classNames.length != 2 ) sys.error(s"expected 2 classname's, actual result: " + classNames.length)
|
||||
if( classNames.toSet != Set("my.scalatest.MyInnerSuite") ) sys.error(s"wrong class names: ${classNames.mkString(", ")}")
|
||||
|
||||
val actualTestName = (testsuite \ "testcase").map(_ \@ "name")
|
||||
if( actualTestName.toSet != Set("Inner passing test should pass", "Inner failing test should fail")) sys.error(s"wrong test names: ${actualTestName.mkString(", ")}")
|
||||
}
|
||||
|
||||
// TODO check console output is in the report
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,11 +6,16 @@ package my.scalatest {
|
|||
|
||||
}
|
||||
|
||||
it should "also pass with file.extension" in {
|
||||
|
||||
}
|
||||
|
||||
"Failing test" should "fail" in {
|
||||
sys.error("wah wah")
|
||||
}
|
||||
}
|
||||
|
||||
@DoNotDiscover
|
||||
class MyInnerSuite(arg: String) extends FlatSpec {
|
||||
"Inner passing test" should "pass" in {
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
def this(outputDir: String) = this(outputDir, null)
|
||||
|
||||
/**Current hostname so we know which machine executed the tests*/
|
||||
val hostname = {
|
||||
val hostname: String = {
|
||||
val start = System.nanoTime
|
||||
val name = try InetAddress.getLocalHost.getHostName
|
||||
catch {
|
||||
|
|
@ -59,7 +59,7 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
val targetDir = new File(outputDir + "/test-reports/")
|
||||
|
||||
/**all system properties as XML*/
|
||||
val properties =
|
||||
val properties: Elem =
|
||||
<properties>
|
||||
{
|
||||
// create a clone, defending against [[ConcurrentModificationException]]
|
||||
|
|
@ -84,7 +84,7 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
val events: ListBuffer[TEvent] = new ListBuffer()
|
||||
|
||||
/**Adds one test result to this suite.*/
|
||||
def addEvent(e: TEvent) = events += e
|
||||
def addEvent(e: TEvent): ListBuffer[TEvent] = events += e
|
||||
|
||||
/** Returns the number of tests of each state for the specified. */
|
||||
def count(status: TStatus) = events.count(_.status == status)
|
||||
|
|
@ -103,6 +103,9 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
TStatus.Pending
|
||||
)
|
||||
|
||||
// for sbt/junit-interface version 0.11 (in future versions this should be done there)
|
||||
val classnameRegex = s"^($name|${name.split('.').last})\\.?".r
|
||||
|
||||
val result =
|
||||
<testsuite hostname={hostname} name={name} tests={tests + ""} errors={errors + ""} failures={
|
||||
failures + ""
|
||||
|
|
@ -112,12 +115,19 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
{properties}
|
||||
{
|
||||
for (e <- events)
|
||||
yield <testcase classname={name} name={
|
||||
yield <testcase classname={
|
||||
e.selector match {
|
||||
case selector: TestSelector => selector.testName.split('.').last
|
||||
case nested: NestedTestSelector =>
|
||||
nested.suiteId().split('.').last + "." + nested.testName()
|
||||
case other => s"(It is not a test it is a ${other.getClass.getCanonicalName})"
|
||||
case nested: NestedTestSelector => nested.suiteId()
|
||||
case _ => name
|
||||
}
|
||||
} name={
|
||||
e.selector match {
|
||||
case selector: TestSelector =>
|
||||
val matchEnd =
|
||||
classnameRegex.findFirstMatchIn(selector.testName).map(_.end).getOrElse(0)
|
||||
selector.testName.substring(matchEnd)
|
||||
case nested: NestedTestSelector => nested.testName()
|
||||
case other => s"(It is not a test it is a ${other.getClass.getCanonicalName})"
|
||||
}
|
||||
} time={(e.duration() / 1000.0).toString}>
|
||||
{
|
||||
|
|
@ -161,11 +171,11 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
override def initialValue(): Option[TestSuite] = None
|
||||
}
|
||||
|
||||
private def withTestSuite[T](f: TestSuite => T) =
|
||||
private def withTestSuite[T](f: TestSuite => T): T =
|
||||
testSuite.get().map(f).getOrElse(sys.error("no test suite"))
|
||||
|
||||
/**Creates the output Dir*/
|
||||
override def doInit() = {
|
||||
override def doInit(): Unit = {
|
||||
val _ = targetDir.mkdirs()
|
||||
}
|
||||
|
||||
|
|
@ -203,9 +213,9 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
* <system-err><![CDATA[]]></system-err>
|
||||
* </testsuite>
|
||||
*/
|
||||
override def endGroup(name: String, t: Throwable) = {
|
||||
override def endGroup(name: String, t: Throwable): Unit = {
|
||||
// create our own event to record the error
|
||||
val event = new TEvent {
|
||||
val event: TEvent = new TEvent {
|
||||
def fullyQualifiedName = name
|
||||
//def description =
|
||||
//"Throwable escaped the test run of '%s'".format(name)
|
||||
|
|
@ -223,7 +233,7 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
* Ends the current suite, wraps up the result and writes it to an XML file
|
||||
* in the output folder that is named after the suite.
|
||||
*/
|
||||
override def endGroup(name: String, result: TestResult) = {
|
||||
override def endGroup(name: String, result: TestResult): Unit = {
|
||||
writeSuite()
|
||||
}
|
||||
|
||||
|
|
@ -237,7 +247,7 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
private[this] def formatISO8601DateTime(d: LocalDateTime): String =
|
||||
d.truncatedTo(ChronoUnit.SECONDS).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||
|
||||
private def writeSuite() = {
|
||||
private def writeSuite(): Unit = {
|
||||
val legacyFile =
|
||||
new File(targetDir, s"${normalizeName(withTestSuite(_.name))}.xml").getAbsolutePath
|
||||
val file =
|
||||
|
|
@ -245,8 +255,8 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
|||
// TODO would be nice to have a logger and log this with level debug
|
||||
// System.err.println("Writing JUnit XML test report: " + file)
|
||||
val testSuiteResult = withTestSuite(_.stop())
|
||||
XML.save(legacyFile, testSuiteResult, "UTF-8", true, null)
|
||||
XML.save(file, testSuiteResult, "UTF-8", true, null)
|
||||
XML.save(legacyFile, testSuiteResult, "UTF-8", xmlDecl = true, null)
|
||||
XML.save(file, testSuiteResult, "UTF-8", xmlDecl = true, null)
|
||||
testSuite.remove()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue