Skip to content

Commit 5cbcd1e

Browse files
committed
Make the JUnit formatter handle empty scenarios. Fixes #774.
Previously the JUnit formatter threw a NPE if a scenario had no steps.
1 parent 48f95df commit 5cbcd1e

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

core/src/main/java/cucumber/runtime/formatter/JUnitFormatter.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ public void startOfScenarioLifeCycle(Scenario scenario) {
124124

125125
@Override
126126
public void endOfScenarioLifeCycle(Scenario scenario) {
127-
// NoOp
127+
if (testCase != null && testCase.steps.isEmpty()) {
128+
testCase.handleEmptyTestCase(doc, root);
129+
}
128130
}
129131

130132
private void addDummyTestCase() {
@@ -140,7 +142,6 @@ private void addDummyTestCase() {
140142
@Override
141143
public void result(Result result) {
142144
testCase.results.add(result);
143-
144145
testCase.updateElement(doc, root);
145146
}
146147

@@ -314,6 +315,15 @@ public void updateElement(Document doc, Element tc) {
314315
}
315316
}
316317

318+
public void handleEmptyTestCase(Document doc, Element tc) {
319+
tc.setAttribute("time", calculateTotalDurationString());
320+
321+
String resultType = treatSkippedAsFailure ? "failure" : "skipped";
322+
Element child = createElementWithMessage(doc, new StringBuilder(), resultType, "The scenario has no steps");
323+
324+
tc.appendChild(child);
325+
}
326+
317327
private String calculateTotalDurationString() {
318328
long totalDurationNanos = 0;
319329
for (Result r : results) {

core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -525,12 +525,29 @@ public void should_handle_one_step_at_the_time_execution() throws Exception {
525525
assertXmlEqual(expected, actual);
526526
}
527527

528+
@Test
529+
public void should_handle_empty_scenarios() throws Throwable {
530+
CucumberFeature feature = TestHelper.feature("path/test.feature",
531+
"Feature: feature name\n" +
532+
" Scenario: scenario name\n");
533+
534+
String formatterOutput = runFeatureWithJUnitFormatter(feature);
535+
536+
String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
537+
"<testsuite failures=\"0\" name=\"cucumber.runtime.formatter.JUnitFormatter\" skipped=\"1\" tests=\"1\" time=\"0\">\n" +
538+
" <testcase classname=\"feature name\" name=\"scenario name\" time=\"0\">\n" +
539+
" <skipped message=\"The scenario has no steps\" />\n" +
540+
" </testcase>\n" +
541+
"</testsuite>\n";
542+
assertXmlEqual(expected, formatterOutput);
543+
}
544+
528545
@Test
529546
public void should_add_dummy_testcase_if_no_scenarios_are_run_to_aviod_failed_jenkins_jobs() throws Throwable {
530547
CucumberFeature feature = TestHelper.feature("path/test.feature",
531548
"Feature: feature name\n");
532549

533-
String formatterOutput = runFeatureWithJUnitFormatter(feature, Collections.<String, String>emptyMap(), Collections.<SimpleEntry<String, String>>emptyList(), milliSeconds(1));
550+
String formatterOutput = runFeatureWithJUnitFormatter(feature);
534551

535552
String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
536553
"<testsuite failures=\"0\" name=\"cucumber.runtime.formatter.JUnitFormatter\" skipped=\"0\" time=\"0\">\n" +
@@ -566,6 +583,10 @@ private File runFeaturesWithJunitFormatter(final List<String> featurePaths, bool
566583
return report;
567584
}
568585

586+
private String runFeatureWithJUnitFormatter(final CucumberFeature feature) throws Throwable {
587+
return runFeatureWithJUnitFormatter(feature, new HashMap<String, String>(), 0L);
588+
}
589+
569590
private String runFeatureWithJUnitFormatter(final CucumberFeature feature, final Map<String, String> stepsToResult, final long stepHookDuration)
570591
throws Throwable {
571592
return runFeatureWithJUnitFormatter(feature, stepsToResult, Collections.<SimpleEntry<String, String>>emptyList(), stepHookDuration);

0 commit comments

Comments
 (0)