diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java index 7a9a019d9d..62299da4ea 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java @@ -48,42 +48,45 @@ import static org.apache.maven.plugin.surefire.report.ReportEntryType.SUCCESS; import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank; -@SuppressWarnings({"javadoc", "checkstyle:javadoctype"}) // CHECKSTYLE_OFF: LineLength -/* +/** * XML format reporter writing to TEST-reportName[-suffix].xml file like written and read * by Ant's <junit> and * <junitreport> tasks, * then supported by many tools like CI servers. *
- *
<?xml version="1.0" encoding="UTF-8"?>
- * <testsuite name="suite name" [group="group"] tests="0" failures="0" errors="0" skipped="0" time="0,###.###">
- *  <properties>
- *    <property name="name" value="value"/>
+ * 
<?xml version="1.0" encoding="UTF-8"?>
+ * <testsuite name="suite name" [group="group"] tests="0" failures="0" errors="0" skipped="0" time="{float}">
+ *  <properties>
+ *    <property name="name" value="value"/>
  *    [...]
- *  </properties>
- *  <testcase time="0,###.###" name="test name [classname="class name"] [group="group"]"/>
- *  <testcase time="0,###.###" name="test name [classname="class name"] [group="group"]">
- *    <error message="message" type="exception class name">stacktrace</error>
- *    <system-out>system out content (present only if not empty)</system-out>
- *    <system-err>system err content (present only if not empty)</system-err>
- *  </testcase>
- *  <testcase time="0,###.###" name="test name [classname="class name"] [group="group"]">
- *    <failure message="message" type="exception class name">stacktrace</failure>
- *    <system-out>system out content (present only if not empty)</system-out>
- *    <system-err>system err content (present only if not empty)</system-err>
- *  </testcase>
- *  <testcase time="0,###.###" name="test name [classname="class name"] [group="group"]">
- *    <skipped/>
- *  </testcase>
+ *  </properties>
+ *  <testcase time="{float}" name="test name [classname="class name"] [group="group"]"/>
+ *  <testcase time="{float}" name="test name [classname="class name"] [group="group"]">
+ *    <error message="message" type="exception class name">stacktrace</error>
+ *    <system-out>system out content (present only if not empty)</system-out>
+ *    <system-err>system err content (present only if not empty)</system-err>
+ *  </testcase>
+ *  <testcase time="{float}" name="test name [classname="class name"] [group="group"]">
+ *    <failure message="message" type="exception class name">stacktrace</failure>
+ *    <system-out>system out content (present only if not empty)</system-out>
+ *    <system-err>system err content (present only if not empty)</system-err>
+ *  </testcase>
+ *  <testcase time="{float}" name="test name [classname="class name"] [group="group"]">
+ *    <skipped/>
+ *  </testcase>
  *  [...]
* * @author Kristian Rosenvold - * @see Ant's format enhancement proposal + * @see Ant's format enhancement proposal * (not yet implemented by Ant 1.8.2) + * @see Ant's XMLJUnitResultFormatter */ -// todo this is no more stateless due to existence of testClassMethodRunHistoryMap since of 2.19. +@SuppressWarnings({"javadoc", "checkstyle:javadoctype"}) +// TODO this is no more stateless due to existence of testClassMethodRunHistoryMap since of 2.19. public class StatelessXmlReporter implements StatelessReportEventListener { + private static final float ONE_SECOND = 1000.0f; + private static final String XML_INDENT = " "; private static final String XML_NL = "\n"; @@ -387,7 +390,9 @@ private void startTestElement(XMLWriter ppw, WrappedReportEntry report) throws I ppw.addAttribute("classname", extraEscapeAttribute(className)); } - ppw.addAttribute("time", report.elapsedTimeAsString()); + if (report.getElapsed() != null) { + ppw.addAttribute("time", String.valueOf(report.getElapsed() / ONE_SECOND)); + } } private void createTestSuiteElement(XMLWriter ppw, WrappedReportEntry report, TestSetStats testSetStats) @@ -407,7 +412,9 @@ private void createTestSuiteElement(XMLWriter ppw, WrappedReportEntry report, Te ppw.addAttribute("group", report.getGroup()); } - ppw.addAttribute("time", report.elapsedTimeAsString()); + if (report.getElapsed() != null) { + ppw.addAttribute("time", String.valueOf(report.getElapsed() / ONE_SECOND)); + } ppw.addAttribute("tests", String.valueOf(testSetStats.getCompletedCount())); diff --git a/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/TestSuiteXmlParser.java b/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/TestSuiteXmlParser.java index 3cc15a6703..eabe10046b 100644 --- a/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/TestSuiteXmlParser.java +++ b/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/TestSuiteXmlParser.java @@ -26,8 +26,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; -import java.text.NumberFormat; -import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -40,15 +38,12 @@ import org.xml.sax.helpers.DefaultHandler; import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Locale.ENGLISH; import static org.apache.maven.shared.utils.StringUtils.isBlank; /** * */ public final class TestSuiteXmlParser extends DefaultHandler { - private final NumberFormat numberFormat = NumberFormat.getInstance(ENGLISH); - private final ConsoleLogger consoleLogger; private ReportTestSuite defaultSuite; @@ -111,13 +106,11 @@ public void startElement(String uri, String localName, String qName, Attributes case "testsuite": defaultSuite = new ReportTestSuite(); currentSuite = defaultSuite; - - try { - Number time = numberFormat.parse(attributes.getValue("time")); - - defaultSuite.setTimeElapsed(time.floatValue()); - } catch (NullPointerException e) { - consoleLogger.error("WARNING: no time attribute found on testsuite element"); + String timeStr = attributes.getValue("time"); + if (timeStr != null) { + defaultSuite.setTimeElapsed(Float.parseFloat(timeStr)); + } else { + consoleLogger.warning("No time attribute found on testsuite element"); } final String name = attributes.getValue("name"); @@ -151,13 +144,12 @@ public void startElement(String uri, String localName, String qName, Attributes } } - String timeAsString = attributes.getValue("time"); - Number time = isBlank(timeAsString) ? 0 : numberFormat.parse(timeAsString); + timeStr = attributes.getValue("time"); testCase.setFullClassName(currentSuite.getFullClassName()) .setClassName(currentSuite.getName()) .setFullName(currentSuite.getFullClassName() + "." + testCase.getName()) - .setTime(time.floatValue()); + .setTime(timeStr != null ? Float.parseFloat(timeStr) : 0.0f); if (currentSuite != defaultSuite) { currentSuite.setTimeElapsed(testCase.getTime() + currentSuite.getTimeElapsed()); @@ -193,8 +185,8 @@ public void startElement(String uri, String localName, String qName, Attributes default: break; } - } catch (ParseException e) { - throw new SAXException(e.getMessage(), e); + } catch (NumberFormatException e) { + throw new SAXException("Failed to parse time value", e); } } } @@ -215,10 +207,9 @@ public void endElement(String uri, String localName, String qName) throws SAXExc break; case "time": try { - defaultSuite.setTimeElapsed( - numberFormat.parse(currentElement.toString()).floatValue()); - } catch (ParseException e) { - throw new SAXException(e.getMessage(), e); + defaultSuite.setTimeElapsed(Float.parseFloat(currentElement.toString())); + } catch (NumberFormatException e) { + throw new SAXException("Failed to parse time value", e); } break; default: