Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve the support of JUnit XML report (#3135)
# JUnit XML Rework the JUnit XML reporting feature. After a couple of tests, the XML report output is not compliant with the "standard" I try to make it more compliant without breaking the great first solution! I took inspiration from the pseudo specification and SBT implementation. One important point is that Maven and SBT are producing one output file per `<testsuite>` a.k.a. per test (spec...) class while this solution (original) is producing one `<testsuites>` output file for the entire module. The specification supports it. We should keep this approach. In this PR: * Follow the "specification" provided in https://github.com/testmoapp/junitxml * Fix the failure/error reporting as there is not necessarily an exception and error message provided (optional) * Call the junit report from `testLocal` * Make sure all the test module types call the same code for junit report: `TestModule`, `ScalaJSModule`, `ScalaNativeModule` ## Resources * Specification (more or less): https://github.com/testmoapp/junitxml * Sbt Inspiration: https://github.com/sbt/sbt/blob/72bfb3f45ab346ddf3558bc23853dfbb9392cc55/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala ## Maven output One output per test class: `target/surefire-reports/TEST-io.ultra.AppTest.xml` ``` <?xml version="1.0" encoding="UTF-8"?> <testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd" name="io.ultra.AppTest" time="0.009" tests="4" errors="1" skipped="0" failures="2"> <properties> <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/> ... <property name="java.class.version" value="55.0"/> </properties> <testcase name="testApp" classname="io.ultra.AppTest" time="0"/> <testcase name="testFailAssertionApp" classname="io.ultra.AppTest" time="0.003"> <failure type="junit.framework.AssertionFailedError">junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:47) at junit.framework.Assert.assertTrue(Assert.java:20) at junit.framework.Assert.assertTrue(Assert.java:27) at io.ultra.AppTest.testFailAssertionApp(AppTest.java:41) </failure> </testcase> <testcase name="testFailApp" classname="io.ultra.AppTest" time="0"> <failure type="junit.framework.AssertionFailedError">junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:47) at junit.framework.Assert.fail(Assert.java:53) at io.ultra.AppTest.testFailApp(AppTest.java:46) </failure> </testcase> <testcase name="testErrorApp" classname="io.ultra.AppTest" time="0.001"> <error message="big error" type="java.lang.RuntimeException">java.lang.RuntimeException: big error at io.ultra.AppTest.testErrorApp(AppTest.java:51) </error> </testcase> </testsuite> ``` ## mill test output Examples vs SBT ### UTest ``` { "fullyQualifiedName": "foo.FooTests", "selector": "foo.FooTests.simple", "duration": 26, "status": "Success" }, { "fullyQualifiedName": "foo.FooTests", "selector": "foo.FooTests.escaping", "duration": 0, "status": "Success" } ``` ### ZIO test ``` { "fullyQualifiedName": "io.ultra.uniq.indexer.ATestSuite", "selector": "root - test-case-1", "duration": 16, "status": "Success" }, { "fullyQualifiedName": "io.ultra.uniq.indexer.ATestSuite", "selector": "root - sub-suite - test-case-2.1", "duration": 17, "status": "Success" }, { "fullyQualifiedName": "io.ultra.uniq.indexer.ATestSuite", "selector": "root - test-case-2", "duration": 18, "status": "Success" }, { "fullyQualifiedName": "io.ultra.uniq.indexer.ATestSuite", "selector": "root - sub-suite - test-case-2.2", "duration": 17, "status": "Success" }, ``` sbt output: ``` <?xml version='1.0' encoding='UTF-8'?> <testsuite hostname="ultra-lapttop-roro" name="io.ultra.uniq.indexer.ATestSuite" tests="4" errors="0" failures="0" skipped="0" time="1.045" timestamp="2024-04-24T17:27:38"> <properties> <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/> ... <property name="jna.nosys" value="true"/> <property name="java.runtime.name" value="OpenJDK Runtime Environment"/> <property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/> <property name="jna.platform.library.path" value="/usr/lib64:/lib64:/usr/lib:/lib:/usr/lib32:/usr/lib/opencollada:/opt/intel/oneapi/tbb/latest/lib/intel64/gcc4.8:/opt/intel/oneapi/compiler/latest/linux/lib:/opt/intel/oneapi/compiler/latest/linux/compiler/lib/intel64_lin"/> <property name="java.vendor.url.bug" value="https://github.com/adoptium/adoptium-support/issues"/> <property name="user.dir" value="/home/rogilles/sandbox/ultra/platform"/> <property name="os.arch" value="amd64"/> <property name="grouping.with.qualified.names.enabled" value="true"/> <property name="idea.managed" value="true"/> <property name="java.vm.info" value="mixed mode"/> <property name="java.vm.version" value="11.0.23+9"/> <property name="java.class.version" value="55.0"/> </properties> <testcase classname="io.ultra.uniq.indexer.ATestSuite" name="root - test-case-1" time="0.256"> </testcase> <testcase classname="io.ultra.uniq.indexer.ATestSuite" name="root - test-case-2" time="0.272"> </testcase> <testcase classname="io.ultra.uniq.indexer.ATestSuite" name="root - sub-suite - test-case-2.1" time="0.259"> </testcase> <testcase classname="io.ultra.uniq.indexer.ATestSuite" name="root - sub-suite - test-case-2.2" time="0.258"> </testcase> <system-out><![CDATA[]]></system-out> <system-err><![CDATA[]]></system-err> </testsuite> ``` ### scalatest #### FreeSpec ``` { "fullyQualifiedName": "io.ultra.cloudevent.ATestSuiteFreeSpec", "selector": "A Set when empty should have size 0", "duration": 2, "status": "Success" }, { "fullyQualifiedName": "io.ultra.cloudevent.ATestSuiteFreeSpec", "selector": "A Set when empty should produce NoSuchElementException when head is invoked", "duration": 1, "status": "Success" }, { "fullyQualifiedName": "io.ultra.cloudevent.ATestSuiteFreeSpec", "selector": "A Set when non-empty should have size > 0", "duration": 0, "status": "Success" } ``` sbt output: ``` <?xml version='1.0' encoding='UTF-8'?> <testsuite hostname="ultra-lapttop-roro" name="io.ultra.cloudevent.ATestSuiteFreeSpec" tests="3" errors="0" failures="0" skipped="0" time="0.016" timestamp="2024-04-24T18:08:19"> <properties> <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/> <property name="java.specification.version" value="11"/> ... <property name="java.class.version" value="55.0"/> </properties> <testcase classname="io.ultra.cloudevent.ATestSuiteFreeSpec" name="A Set when empty should have size 0" time="0.014"> </testcase> <testcase classname="io.ultra.cloudevent.ATestSuiteFreeSpec" name="A Set when empty should produce NoSuchElementException when head is invoked" time="0.0"> </testcase> <testcase classname="io.ultra.cloudevent.ATestSuiteFreeSpec" name="A Set when non-empty should have size > 0" time="0.002"> </testcase> <system-out><![CDATA[]]></system-out> <system-err><![CDATA[]]></system-err> </testsuite> ``` #### FlatSpec ``` { "fullyQualifiedName": "io.ultra.cloudevent.ATestSuiteFlatSpec", "selector": "root should work 1", "duration": 16, "status": "Success" }, { "fullyQualifiedName": "io.ultra.cloudevent.ATestSuiteFlatSpec", "selector": "root should work 2", "duration": 0, "status": "Success" }, ``` sbt output: ``` <?xml version='1.0' encoding='UTF-8'?> <testsuite hostname="ultra-lapttop-roro" name="io.ultra.cloudevent.ATestSuiteFlatSpec" tests="2" errors="0" failures="0" skipped="0" time="0.017" timestamp="2024-04-24T18:08:19"> <properties> <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/> ... <property name="java.class.version" value="55.0"/> </properties> <testcase classname="io.ultra.cloudevent.ATestSuiteFlatSpec" name="root should work 1" time="0.017"> </testcase> <testcase classname="io.ultra.cloudevent.ATestSuiteFlatSpec" name="root should work 2" time="0.0"> </testcase> <system-out><![CDATA[]]></system-out> <system-err><![CDATA[]]></system-err> </testsuite> ``` Pull request: #3135
- Loading branch information