From 86bd2694fc517e11048814f7165ab1e5a28d29f0 Mon Sep 17 00:00:00 2001 From: brasmusson Date: Thu, 13 Jun 2013 15:14:19 +0200 Subject: [PATCH] JUnitFormatter marks skipped tests as failures in strict mode Let the option strict make JUnitFormatter to mark skipped tests as failures. Use a new interface StrictAware to determine which formatters the strict option should be passed to, following the example of the interface ColorAware determining which formatters the monochrome option is sent to. --- .../java/cucumber/runtime/RuntimeOptions.java | 36 +++++++++++++++---- .../runtime/formatter/JUnitFormatter.java | 16 +++++++-- .../runtime/formatter/StrictAware.java | 5 +++ .../cucumber/runtime/RuntimeOptionsTest.java | 31 ++++++++++++++++ .../runtime/formatter/JUnitFormatterTest.java | 14 ++++++++ .../JUnitFormatterTest_1_strict.report.xml | 15 ++++++++ 6 files changed, 108 insertions(+), 9 deletions(-) create mode 100755 core/src/main/java/cucumber/runtime/formatter/StrictAware.java create mode 100755 core/src/test/resources/cucumber/runtime/formatter/JUnitFormatterTest_1_strict.report.xml diff --git a/core/src/main/java/cucumber/runtime/RuntimeOptions.java b/core/src/main/java/cucumber/runtime/RuntimeOptions.java index 582c8716bd..f69bc6ae27 100644 --- a/core/src/main/java/cucumber/runtime/RuntimeOptions.java +++ b/core/src/main/java/cucumber/runtime/RuntimeOptions.java @@ -2,6 +2,7 @@ import cucumber.runtime.formatter.ColorAware; import cucumber.runtime.formatter.FormatterFactory; +import cucumber.runtime.formatter.StrictAware; import cucumber.runtime.io.ResourceLoader; import cucumber.runtime.model.CucumberFeature; import gherkin.formatter.Formatter; @@ -31,7 +32,7 @@ public class RuntimeOptions { public final List filters = new ArrayList(); public final List formatters = new ArrayList(); public final List featurePaths = new ArrayList(); - private final FormatterFactory formatterFactory = new FormatterFactory(); + private final FormatterFactory formatterFactory; public URL dotCucumber; public boolean dryRun; public boolean strict = false; @@ -39,6 +40,11 @@ public class RuntimeOptions { public RuntimeOptions(Properties properties, String... argv) { /* IMPORTANT! Make sure USAGE.txt is always uptodate if this class changes */ + this(properties, new FormatterFactory(), argv); + } + + RuntimeOptions(Properties properties, FormatterFactory formatterFactory, String... argv) { + this.formatterFactory = formatterFactory; parse(new ArrayList(asList(argv))); if (properties.containsKey("cucumber.options")) { @@ -48,12 +54,7 @@ public RuntimeOptions(Properties properties, String... argv) { if (formatters.isEmpty()) { formatters.add(formatterFactory.create("progress")); } - for (Formatter formatter : formatters) { - if (formatter instanceof ColorAware) { - ColorAware colorAware = (ColorAware) formatter; - colorAware.setMonochrome(monochrome); - } - } + setFormatterOptions(); } private List cucumberOptionsSplit(String property) { @@ -149,4 +150,25 @@ public Object invoke(Object target, Method method, Object[] args) throws Throwab } }); } + + private void setFormatterOptions() { + for (Formatter formatter : formatters) { + setMonochromeOnColorAwareFormatters(formatter); + setStrictOnStrictAwareFormatters(formatter); + } + } + + private void setMonochromeOnColorAwareFormatters(Formatter formatter) { + if (formatter instanceof ColorAware) { + ColorAware colorAware = (ColorAware) formatter; + colorAware.setMonochrome(monochrome); + } + } + + private void setStrictOnStrictAwareFormatters(Formatter formatter) { + if (formatter instanceof StrictAware) { + StrictAware strictAware = (StrictAware) formatter; + strictAware.setStrict(strict); + } + } } diff --git a/core/src/main/java/cucumber/runtime/formatter/JUnitFormatter.java b/core/src/main/java/cucumber/runtime/formatter/JUnitFormatter.java index 012f5a90f6..9d58a1de64 100644 --- a/core/src/main/java/cucumber/runtime/formatter/JUnitFormatter.java +++ b/core/src/main/java/cucumber/runtime/formatter/JUnitFormatter.java @@ -36,7 +36,7 @@ import java.util.List; import java.util.Locale; -class JUnitFormatter implements Formatter, Reporter { +class JUnitFormatter implements Formatter, Reporter, StrictAware { private final Writer out; private final Document doc; private final Element rootElement; @@ -170,6 +170,11 @@ public void eof() { public void syntaxError(String state, String event, List legalEvents, String uri, Integer line) { } + @Override + public void setStrict(boolean strict) { + TestCase.treatSkippedAsFailure = strict; + } + private static class TestCase { private static final DecimalFormat NUMBER_FORMAT = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); @@ -187,6 +192,7 @@ private TestCase() { Scenario scenario; static Feature feature; static int examples = 0; + static boolean treatSkippedAsFailure = false; final List steps = new ArrayList(); final List results = new ArrayList(); @@ -232,7 +238,13 @@ public void updateElement(Document doc, Element tc) { child.setAttribute("message", failed.getErrorMessage()); child.appendChild(doc.createCDATASection(sb.toString())); } else if (skipped != null) { - child = doc.createElement("skipped"); + if (treatSkippedAsFailure) { + child = doc.createElement("failure"); + child.setAttribute("message", "The scenario has pending or undefined step(s)"); + } + else { + child = doc.createElement("skipped"); + } child.appendChild(doc.createCDATASection(sb.toString())); } else { child = doc.createElement("system-out"); diff --git a/core/src/main/java/cucumber/runtime/formatter/StrictAware.java b/core/src/main/java/cucumber/runtime/formatter/StrictAware.java new file mode 100755 index 0000000000..4037a87fbc --- /dev/null +++ b/core/src/main/java/cucumber/runtime/formatter/StrictAware.java @@ -0,0 +1,5 @@ +package cucumber.runtime.formatter; + +public interface StrictAware { + public void setStrict(boolean strict); +} diff --git a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java index d57380b01a..9a7fea8465 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java @@ -2,6 +2,12 @@ import org.junit.Test; +import cucumber.runtime.formatter.ColorAware; +import cucumber.runtime.formatter.FormatterFactory; +import cucumber.runtime.formatter.StrictAware; + +import gherkin.formatter.Formatter; + import java.net.MalformedURLException; import java.net.URL; import java.util.Properties; @@ -12,6 +18,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; public class RuntimeOptionsTest { @Test @@ -165,4 +175,25 @@ public void fail_on_unsupported_options() { } } + @Test + public void set_monochrome_on_color_aware_formatters() throws Exception { + FormatterFactory factory = mock(FormatterFactory.class); + Formatter colorAwareFormatter = mock(Formatter.class, withSettings().extraInterfaces(ColorAware.class)); + when(factory.create("progress")).thenReturn(colorAwareFormatter); + + new RuntimeOptions(new Properties(), factory, "--monochrome", "--format", "progress"); + + verify((ColorAware)colorAwareFormatter).setMonochrome(true); + } + + @Test + public void set_strict_on_strict_aware_formatters() throws Exception { + FormatterFactory factory = mock(FormatterFactory.class); + Formatter strictAwareFormatter = mock(Formatter.class, withSettings().extraInterfaces(StrictAware.class)); + when(factory.create("junit:out/dir")).thenReturn(strictAwareFormatter); + + new RuntimeOptions(new Properties(), factory, "--strict", "--format", "junit:out/dir"); + + verify((StrictAware)strictAwareFormatter).setStrict(true); + } } diff --git a/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java b/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java index 70fc5e693d..d78860f556 100644 --- a/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java @@ -45,12 +45,26 @@ public void featureWithOutlineTest() throws Exception { assertXmlEqual("cucumber/runtime/formatter/JUnitFormatterTest_3.report.xml", report); } + @Test + public void featureSimpleStrictTest() throws Exception { + boolean strict = true; + File report = runFeaturesWithJunitFormatter(asList("cucumber/runtime/formatter/JUnitFormatterTest_1.feature"), strict); + assertXmlEqual("cucumber/runtime/formatter/JUnitFormatterTest_1_strict.report.xml", report); + } + private File runFeaturesWithJunitFormatter(final List featurePaths) throws IOException { + return runFeaturesWithJunitFormatter(featurePaths, false); + } + + private File runFeaturesWithJunitFormatter(final List featurePaths, boolean strict) throws IOException { File report = File.createTempFile("cucumber-jvm-junit", "xml"); final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader(classLoader); List args = new ArrayList(); + if (strict) { + args.add("--strict"); + } args.add("--format"); args.add("junit:" + report.getAbsolutePath()); args.addAll(featurePaths); diff --git a/core/src/test/resources/cucumber/runtime/formatter/JUnitFormatterTest_1_strict.report.xml b/core/src/test/resources/cucumber/runtime/formatter/JUnitFormatterTest_1_strict.report.xml new file mode 100755 index 0000000000..e4d186b762 --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/formatter/JUnitFormatterTest_1_strict.report.xml @@ -0,0 +1,15 @@ + + + + + + + + +