Skip to content

Commit a78287a

Browse files
Escape invalid XML chars in testCase and testSuite names (#284)
With a [ParameterizedTest](https://junit.org/junit5/docs/5.0.2/api/org/junit/jupiter/params/ParameterizedTest.html) it is possible to generate test case names with invalid XML characters. E.g. ``` @ParameterizedTest @valuesource(strings = {"Weird\bname"}) void testFoo(String input) { ... } ``` The test case name is derived from the input string, which in this case contains an invalid XML char `\b`. When tools (like IDEs) try to parse the junit XML, they'll fail due to the invalid char. Fix it by escaping test case names. It looks like [test suite names](https://junit.org/junit5/docs/5.0.3/api/org/junit/jupiter/api/DisplayName.html) could also contain invalid XML chars, so I'm escaping those as well. Closes #285
1 parent 2393517 commit a78287a

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

java/src/com/github/bazel_contrib/contrib_rules_jvm/junit5/TestCaseXmlRenderer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void toXml(XMLStreamWriter xml, TestData test) throws XMLStreamException
4747
}
4848

4949
xml.writeStartElement("testcase");
50-
xml.writeAttribute("name", name);
50+
xml.writeAttribute("name", escapeIllegalCharacters(name));
5151
xml.writeAttribute("classname", LegacyReportingUtils.getClassName(testPlan, id));
5252

5353
/* @Nullable */ Duration maybeDuration = test.getDuration();

java/src/com/github/bazel_contrib/contrib_rules_jvm/junit5/TestSuiteXmlRenderer.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.bazel_contrib.contrib_rules_jvm.junit5;
22

3+
import static com.github.bazel_contrib.contrib_rules_jvm.junit5.SafeXml.escapeIllegalCharacters;
34
import static com.github.bazel_contrib.contrib_rules_jvm.junit5.SafeXml.writeTextElement;
45

56
import java.util.Collection;
@@ -19,7 +20,7 @@ public void toXml(XMLStreamWriter xml, TestData suite, Collection<TestData> test
1920
throws XMLStreamException {
2021
xml.writeStartElement("testsuite");
2122

22-
xml.writeAttribute("name", suite.getId().getLegacyReportingName());
23+
xml.writeAttribute("name", escapeIllegalCharacters(suite.getId().getLegacyReportingName()));
2324
xml.writeAttribute("tests", String.valueOf(tests.size()));
2425

2526
int errors = 0;

java/test/com/github/bazel_contrib/contrib_rules_jvm/junit5/BazelJUnitOuputListenerTest.java

+32
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,38 @@ public void ensureOutputsAreProperlyEscaped() {
263263
assertEquals("&#27;[31mAlso bad!&#27;[0m", text);
264264
}
265265

266+
@Test
267+
public void ensureTestCaseNamesAreProperlyEscaped() {
268+
var testDescriptor = new StubbedTestDescriptor(createId("Weird\bname"));
269+
var identifier = TestIdentifier.from(testDescriptor);
270+
271+
var testCaseData = new TestData(identifier);
272+
testCaseData.mark(TestExecutionResult.successful());
273+
274+
Document xml = generateTestXml(Mockito.mock(TestPlan.class), testCaseData);
275+
276+
Node item = xml.getElementsByTagName("testcase").item(0);
277+
String testName = item.getAttributes().getNamedItem("name").getNodeValue();
278+
279+
assertEquals("[engine:mocked]/[class:ExampleTest]/[method:Weird&#8;name", testName);
280+
}
281+
282+
@Test
283+
public void ensureTestSuiteNamesAreProperlyEscaped() {
284+
var testDescriptor = new StubbedTestDescriptor(createId("Weird\bname"));
285+
var identifier = TestIdentifier.from(testDescriptor);
286+
287+
var testSuiteData = new TestData(identifier);
288+
testSuiteData.mark(TestExecutionResult.successful());
289+
290+
Document xml = generateTestXml(Mockito.mock(TestPlan.class), testSuiteData, List.of());
291+
292+
Node item = xml.getElementsByTagName("testsuite").item(0);
293+
String testName = item.getAttributes().getNamedItem("name").getNodeValue();
294+
295+
assertEquals("[engine:mocked]/[class:ExampleTest]/[method:Weird&#8;name()]", testName);
296+
}
297+
266298
private Document generateTestXml(TestPlan testPlan, TestData testCase) {
267299
return generateDocument(xml -> new TestCaseXmlRenderer(testPlan).toXml(xml, testCase));
268300
}

0 commit comments

Comments
 (0)