Skip to content

Commit f451db8

Browse files
committed
Replace the JUnitFormatter with the message based implementation from
[cucumber-junit-xml-formatter](https://github.com/cucumber/cucumber-junit-xml-formatter). This achieves several goals: * Move the internal code base away from the events from the `plugin` module. * Extract common parts of Cucumber into modules that can be shared. This results in several changes/improvements: 1. Change the long naming strategy to include the example group index ```feature Feature: Examples Tables Scenario Outline: Eating cucumbers Given there are <start> cucumbers When I eat <eat> cucumbers Then I should have <left> cucumbers Examples: These are passing | start | eat | left | | 12 | 5 | 7 | | 20 | 5 | 15 | Examples: These are failing | start | eat | left | | 12 | 20 | 0 | | 0 | 1 | 0 | ``` This feature previously contained the examples - Examples Tables - Eating cucumbers - These are passing - Example #1 - Examples Tables - Eating cucumbers - These are passing - Example #2 - Examples Tables - Eating cucumbers - These are failing - Example #1 - Examples Tables - Eating cucumbers - These are failing - Example #2 And will now contain the examples: - Examples Tables - Eating cucumbers - These are passing - Example #1.1 - Examples Tables - Eating cucumbers - These are passing - Example #1.2 - Examples Tables - Eating cucumbers - These are failing - Example #2.1 - Examples Tables - Eating cucumbers - These are failing - Example #2.2 2. Rename the suite from `io.cucumber.core.plugin.JUnitFormatter` to `Cucumber` ```xml <testsuite failures="0" name="Cucumber" skipped="0" errors="0" tests="1" time="0"> ``` 3. When a scenario is skipped or failed the executed steps are always included in the `system-out` element rather than the `skipped` or `failed` element. ```xml <testcase classname="Examples Tables" name="eating cucumbers - These are failing - Example #2.1" time="0.007"> <failure type="AssertionError" message="Expected values to be strictly equal: -8 !== 0 "> <![CDATA[ <a stacktrace here> ]]> </failure> <system-out><![CDATA[ Given there are 12 cucumbers................................................passed When I eat 20 cucumbers.....................................................passed Then I should have 0 cucumbers..............................................failed ]]></system-out> </testcase> <testcase classname="Skipping scenarios" name="Skipping from a step causes the rest of the scenario to be skipped" time="0.005"> <skipped/> <system-out><![CDATA[ Given a step that skips.....................................................skipped When a step that we expect to be skipped....................................skipped ]]></system-out> </testcase> ``` 4. The empty scenario and empty report are considered passing To be consistent with the exit code of the Cucumber process empty scenarios and test runs are considered passing.
1 parent 4fc8e37 commit f451db8

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

Diff for: cucumber-core/src/test/java/io/cucumber/core/plugin/JUnitFormatterTest.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.opentest4j.TestAbortedException;
1515

1616
import java.io.ByteArrayOutputStream;
17+
import java.io.InputStream;
1718
import java.io.PrintWriter;
1819
import java.io.StringWriter;
1920
import java.util.Arrays;
@@ -27,12 +28,16 @@
2728
import static java.util.Collections.singletonList;
2829
import static org.hamcrest.MatcherAssert.assertThat;
2930
import static org.xmlunit.matchers.CompareMatcher.isIdenticalTo;
31+
import static org.xmlunit.matchers.ValidationMatcher.valid;
3032

3133
class JUnitFormatterTest {
3234

3335
private static void assertXmlEqual(String expected, ByteArrayOutputStream actual) {
3436
String actualString = new String(actual.toByteArray(), UTF_8);
37+
String xsd = "/io/cucumber/core/plugin/surefire-test-report-3.0.xsd";
38+
InputStream schema = JUnitFormatterTest.class.getResourceAsStream(xsd);
3539
assertThat(actualString, isIdenticalTo(expected).ignoreWhitespace());
40+
assertThat(actualString, valid(schema));
3641
}
3742

3843
@Test
@@ -219,7 +224,7 @@ void should_format_skipped_scenario() {
219224
"<testsuite failures=\"0\" name=\"Cucumber\" skipped=\"1\" errors=\"0\" tests=\"1\" time=\"0\">\n"
220225
+
221226
" <testcase classname=\"feature name\" name=\"scenario name\" time=\"0\">\n" +
222-
" <skipped message=\"message\" type=\"org.opentest4j.TestAbortedException\">" +
227+
" <skipped message=\"message\">" +
223228
"<![CDATA["
224229
+ stackTrace +
225230
"]]></skipped>\n" +
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
From: https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd
4+
Via: https://maven.apache.org/surefire/maven-surefire-plugin/
5+
-->
6+
<!--
7+
~ Licensed to the Apache Software Foundation (ASF) under one
8+
~ or more contributor license agreements. See the NOTICE file
9+
~ distributed with this work for additional information
10+
~ regarding copyright ownership. The ASF licenses this file
11+
~ to you under the Apache License, Version 2.0 (the
12+
~ "License"); you may not use this file except in compliance
13+
~ with the License. You may obtain a copy of the License at
14+
~
15+
~ http://www.apache.org/licenses/LICENSE-2.0
16+
~
17+
~ Unless required by applicable law or agreed to in writing,
18+
~ software distributed under the License is distributed on an
19+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20+
~ KIND, either express or implied. See the License for the
21+
~ specific language governing permissions and limitations
22+
~ under the License.
23+
-->
24+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0">
25+
<xs:simpleType name="SUREFIRE_TIME">
26+
<xs:restriction base="xs:string">
27+
<xs:pattern value="(([0-9]{0,3},)*[0-9]{3}|[0-9]{0,3})*(\.[0-9]{0,3})?"/>
28+
</xs:restriction>
29+
</xs:simpleType>
30+
<xs:element name="testsuite">
31+
<xs:complexType>
32+
<xs:sequence>
33+
<xs:element name="properties" minOccurs="0" maxOccurs="unbounded">
34+
<xs:complexType>
35+
<xs:sequence>
36+
<xs:element name="property" minOccurs="0" maxOccurs="unbounded">
37+
<xs:complexType>
38+
<xs:attribute name="name" type="xs:string" use="required"/>
39+
<xs:attribute name="value" type="xs:string" use="required"/>
40+
</xs:complexType>
41+
</xs:element>
42+
</xs:sequence>
43+
</xs:complexType>
44+
</xs:element>
45+
<xs:element name="testcase" minOccurs="0" maxOccurs="unbounded">
46+
<xs:complexType>
47+
<xs:sequence>
48+
<xs:element name="failure" nillable="true" minOccurs="0" maxOccurs="unbounded">
49+
<xs:complexType>
50+
<xs:simpleContent>
51+
<xs:extension base="xs:string">
52+
<xs:attribute name="message" type="xs:string"/>
53+
<xs:attribute name="type" type="xs:string" use="required"/>
54+
</xs:extension>
55+
</xs:simpleContent>
56+
</xs:complexType>
57+
</xs:element>
58+
<xs:element name="rerunFailure" minOccurs="0" maxOccurs="unbounded">
59+
<xs:complexType>
60+
<xs:sequence>
61+
<xs:element name="stackTrace" type="xs:string"/>
62+
<xs:element name="system-out" type="xs:string" minOccurs="0"/>
63+
<xs:element name="system-err" type="xs:string" minOccurs="0"/>
64+
</xs:sequence>
65+
<xs:attribute name="message" type="xs:string"/>
66+
<xs:attribute name="type" type="xs:string" use="required"/>
67+
</xs:complexType>
68+
</xs:element>
69+
<xs:element name="flakyFailure" minOccurs="0" maxOccurs="unbounded">
70+
<xs:complexType>
71+
<xs:sequence>
72+
<xs:element name="stackTrace" type="xs:string"/>
73+
<xs:element name="system-out" type="xs:string" minOccurs="0"/>
74+
<xs:element name="system-err" type="xs:string" minOccurs="0"/>
75+
</xs:sequence>
76+
<xs:attribute name="message" type="xs:string"/>
77+
<xs:attribute name="type" type="xs:string" use="required"/>
78+
</xs:complexType>
79+
</xs:element>
80+
<xs:element name="skipped" nillable="true" minOccurs="0" maxOccurs="1">
81+
<xs:complexType>
82+
<xs:simpleContent>
83+
<xs:extension base="xs:string">
84+
<xs:attribute name="message" type="xs:string"/>
85+
</xs:extension>
86+
</xs:simpleContent>
87+
</xs:complexType>
88+
</xs:element>
89+
<xs:element name="error" nillable="true" minOccurs="0" maxOccurs="1">
90+
<xs:complexType>
91+
<xs:simpleContent>
92+
<xs:extension base="xs:string">
93+
<xs:attribute name="message" type="xs:string"/>
94+
<xs:attribute name="type" type="xs:string" use="required"/>
95+
</xs:extension>
96+
</xs:simpleContent>
97+
</xs:complexType>
98+
</xs:element>
99+
<xs:element name="rerunError" minOccurs="0" maxOccurs="unbounded">
100+
<xs:complexType>
101+
<xs:sequence>
102+
<xs:element name="stackTrace" type="xs:string"/>
103+
<xs:element name="system-out" type="xs:string" minOccurs="0"/>
104+
<xs:element name="system-err" type="xs:string" minOccurs="0"/>
105+
</xs:sequence>
106+
<xs:attribute name="message" type="xs:string"/>
107+
<xs:attribute name="type" type="xs:string" use="required"/>
108+
</xs:complexType>
109+
</xs:element>
110+
<xs:element name="flakyError" minOccurs="0" maxOccurs="unbounded">
111+
<xs:complexType>
112+
<xs:sequence>
113+
<xs:element name="stackTrace" type="xs:string"/>
114+
<xs:element name="system-out" type="xs:string" minOccurs="0"/>
115+
<xs:element name="system-err" type="xs:string" minOccurs="0"/>
116+
</xs:sequence>
117+
<xs:attribute name="message" type="xs:string"/>
118+
<xs:attribute name="type" type="xs:string" use="required"/>
119+
</xs:complexType>
120+
</xs:element>
121+
<xs:element name="system-out" type="xs:string" minOccurs="0"/>
122+
<xs:element name="system-err" type="xs:string" minOccurs="0"/>
123+
</xs:sequence>
124+
<xs:attribute name="name" type="xs:string" use="required"/>
125+
<xs:attribute name="classname" type="xs:string"/>
126+
<xs:attribute name="group" type="xs:string"/>
127+
<xs:attribute name="time" type="SUREFIRE_TIME" use="required"/>
128+
</xs:complexType>
129+
</xs:element>
130+
</xs:sequence>
131+
<xs:attribute name="name" type="xs:string" use="required"/>
132+
<xs:attribute name="time" type="SUREFIRE_TIME"/>
133+
<xs:attribute name="tests" type="xs:string" use="required"/>
134+
<xs:attribute name="errors" type="xs:string" use="required"/>
135+
<xs:attribute name="skipped" type="xs:string" use="required"/>
136+
<xs:attribute name="failures" type="xs:string" use="required"/>
137+
<xs:attribute name="group" type="xs:string"/>
138+
</xs:complexType>
139+
</xs:element>
140+
</xs:schema>

0 commit comments

Comments
 (0)