From 3affec7fb5d771abe521224ca506dd777d1cb004 Mon Sep 17 00:00:00 2001 From: mpkorstanje Date: Fri, 26 May 2017 20:34:36 +0200 Subject: [PATCH] [JUnit] Add --[no-]step-notifications options to JunitOptions When interacting with cucumber in an IDE it is nice to see the step executions. However presenting step executions to surefire as tests results in strange test counts and weird reports. The --no-step-notifications options ensures steps are not included in descriptions and no events are fired for the execution of steps. Related issues: - https://github.com/cucumber/cucumber-jvm/issues/263 - https://github.com/cucumber/cucumber-jvm/issues/577 --- .../runtime/junit/ExecutionUnitRunner.java | 161 ------------- .../cucumber/runtime/junit/FeatureRunner.java | 28 ++- .../cucumber/runtime/junit/JUnitOptions.java | 8 +- .../cucumber/runtime/junit/JUnitReporter.java | 121 ++++++++-- .../cucumber/runtime/junit/PickleRunners.java | 227 ++++++++++++++++++ .../resources/cucumber/api/junit/OPTIONS.txt | 7 +- .../cucumber/runtime/junit/CucumberTest.java | 4 +- .../runtime/junit/FeatureRunnerTest.java | 73 ++++-- .../runtime/junit/JUnitReporterTest.java | 76 +++--- ...ickleRunnerWithNoStepDescriptionsTest.java | 73 ++++++ ...PickleRunnerWithStepDescriptionsTest.java} | 93 ++++--- .../RunCukesTestNoStepNotifications.java | 10 + .../cucumber/runtime/junit/SanityTest.java | 5 + ..._same_steps_in_different_scenarios.feature | 8 - 14 files changed, 609 insertions(+), 285 deletions(-) delete mode 100644 junit/src/main/java/cucumber/runtime/junit/ExecutionUnitRunner.java create mode 100644 junit/src/main/java/cucumber/runtime/junit/PickleRunners.java create mode 100644 junit/src/test/java/cucumber/runtime/junit/PickleRunnerWithNoStepDescriptionsTest.java rename junit/src/test/java/cucumber/runtime/junit/{ExecutionUnitRunnerTest.java => PickleRunnerWithStepDescriptionsTest.java} (60%) create mode 100644 junit/src/test/java/cucumber/runtime/junit/RunCukesTestNoStepNotifications.java delete mode 100644 junit/src/test/resources/cucumber/runtime/junit/feature_with_same_steps_in_different_scenarios.feature diff --git a/junit/src/main/java/cucumber/runtime/junit/ExecutionUnitRunner.java b/junit/src/main/java/cucumber/runtime/junit/ExecutionUnitRunner.java deleted file mode 100644 index 7dc079dd0c..0000000000 --- a/junit/src/main/java/cucumber/runtime/junit/ExecutionUnitRunner.java +++ /dev/null @@ -1,161 +0,0 @@ -package cucumber.runtime.junit; - -import cucumber.runner.Runner; -import gherkin.events.PickleEvent; -import gherkin.pickles.PickleStep; -import org.junit.runner.Description; -import org.junit.runner.notification.RunNotifier; -import org.junit.runners.ParentRunner; -import org.junit.runners.model.InitializationError; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Runs a scenario, or a "synthetic" scenario derived from an Examples row. - */ -class ExecutionUnitRunner extends ParentRunner { - private final Runner runner; - private final PickleEvent pickleEvent; - private final JUnitReporter jUnitReporter; - private final Map stepDescriptions = new HashMap(); - private Description description; - - ExecutionUnitRunner(Runner runner, PickleEvent pickleEvent, JUnitReporter jUnitReporter) throws InitializationError { - super(null); - this.runner = runner; - this.pickleEvent = pickleEvent; - this.jUnitReporter = jUnitReporter; - } - - @Override - protected List getChildren() { - return pickleEvent.pickle.getSteps(); - } - - @Override - public String getName() { - String name = pickleEvent.pickle.getName(); - if (jUnitReporter.useFilenameCompatibleNames()) { - return makeNameFilenameCompatible(name); - } else { - return name; - } - } - - @Override - public Description getDescription() { - if (description == null) { - String nameForDescription = getName().isEmpty() ? "EMPTY_NAME" : getName(); - description = Description.createSuiteDescription(nameForDescription, new PickleId(pickleEvent)); - - for (PickleStep step : getChildren()) { - description.addChild(describeChild(step)); - } - } - return description; - } - - @Override - protected Description describeChild(PickleStep step) { - Description description = stepDescriptions.get(step); - if (description == null) { - String testName; - if (jUnitReporter.useFilenameCompatibleNames()) { - testName = makeNameFilenameCompatible(step.getText()); - } else { - testName = step.getText(); - } - description = Description.createTestDescription(getName(), testName, new PickleStepId(pickleEvent, step)); - stepDescriptions.put(step, description); - } - return description; - } - - @Override - public void run(final RunNotifier notifier) { - jUnitReporter.startExecutionUnit(this, notifier); - // This causes runChild to never be called, which seems OK. - runner.runPickle(pickleEvent); - jUnitReporter.finishExecutionUnit(); - } - - @Override - protected void runChild(PickleStep step, RunNotifier notifier) { - // The way we override run(RunNotifier) causes this method to never be called. - // Instead it happens via cucumberScenario.run(jUnitReporter, jUnitReporter, runtime); - throw new UnsupportedOperationException(); - // cucumberScenario.runStep(step, jUnitReporter, runtime); - } - - private String makeNameFilenameCompatible(String name) { - return name.replaceAll("[^A-Za-z0-9_]", "_"); - } - - private static final class PickleId implements Serializable { - private static final long serialVersionUID = 1L; - private final String uri; - private int pickleLine; - - PickleId(PickleEvent pickleEvent) { - this.uri = pickleEvent.uri; - this.pickleLine = pickleEvent.pickle.getLocations().get(0).getLine(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PickleId that = (PickleId) o; - return pickleLine == that.pickleLine && uri.equals(that.uri); - } - - @Override - public int hashCode() { - int result = uri.hashCode(); - result = 31 * result + pickleLine; - return result; - } - - @Override - public String toString() { - return uri + ":" + pickleLine; - } - } - - private static final class PickleStepId implements Serializable { - private static final long serialVersionUID = 1L; - private final String uri; - private final int pickleLine; - private final int pickleStepLine; - - PickleStepId(PickleEvent pickleEvent, PickleStep pickleStepLine) { - this.uri = pickleEvent.uri; - this.pickleLine = pickleEvent.pickle.getLocations().get(0).getLine(); - this.pickleStepLine = pickleStepLine.getLocations().get(0).getLine(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PickleStepId that = (PickleStepId) o; - return pickleLine == that.pickleLine && pickleStepLine == that.pickleStepLine && uri.equals(that.uri); - } - - @Override - public int hashCode() { - int result = pickleLine; - result = 31 * result + uri.hashCode(); - result = 31 * result + pickleStepLine; - return result; - } - - @Override - public String toString() { - return uri + ":" + pickleLine + ":" + pickleStepLine; - } - } -} \ No newline at end of file diff --git a/junit/src/main/java/cucumber/runtime/junit/FeatureRunner.java b/junit/src/main/java/cucumber/runtime/junit/FeatureRunner.java index 8b474d698c..4cd5d6a53a 100644 --- a/junit/src/main/java/cucumber/runtime/junit/FeatureRunner.java +++ b/junit/src/main/java/cucumber/runtime/junit/FeatureRunner.java @@ -1,7 +1,11 @@ package cucumber.runtime.junit; +import static cucumber.runtime.junit.PickleRunners.withNoStepDescriptions; +import static cucumber.runtime.junit.PickleRunners.withStepDescriptions; + import cucumber.runtime.CucumberException; import cucumber.runtime.Runtime; +import cucumber.runtime.junit.PickleRunners.PickleRunner; import cucumber.runtime.model.CucumberFeature; import gherkin.ast.Feature; import gherkin.events.PickleEvent; @@ -16,8 +20,8 @@ import java.util.ArrayList; import java.util.List; -public class FeatureRunner extends ParentRunner { - private final List children = new ArrayList(); +public class FeatureRunner extends ParentRunner { + private final List children = new ArrayList(); private final CucumberFeature cucumberFeature; private Description description; @@ -38,7 +42,7 @@ public String getName() { public Description getDescription() { if (description == null) { description = Description.createSuiteDescription(getName(), new FeatureId(cucumberFeature)); - for (ParentRunner child : getChildren()) { + for (PickleRunner child : getChildren()) { description.addChild(describeChild(child)); } } @@ -50,17 +54,17 @@ public boolean isEmpty() { } @Override - protected List getChildren() { + protected List getChildren() { return children; } @Override - protected Description describeChild(ParentRunner child) { + protected Description describeChild(PickleRunner child) { return child.getDescription(); } @Override - protected void runChild(ParentRunner child, RunNotifier notifier) { + protected void runChild(PickleRunner child, RunNotifier notifier) { child.run(notifier); } @@ -78,9 +82,15 @@ private void buildFeatureElementRunners(Runtime runtime, JUnitReporter jUnitRepo for (PickleEvent pickleEvent : pickleEvents) { if (runtime.matchesFilters(pickleEvent)) { try { - ParentRunner pickleRunner; - pickleRunner = new ExecutionUnitRunner(runtime.getRunner(), pickleEvent, jUnitReporter); - children.add(pickleRunner); + if(jUnitReporter.stepNotifications()) { + PickleRunner picklePickleRunner; + picklePickleRunner = withStepDescriptions(runtime.getRunner(), pickleEvent, jUnitReporter); + children.add(picklePickleRunner); + } else { + PickleRunner picklePickleRunner; + picklePickleRunner = withNoStepDescriptions(runtime.getRunner(), pickleEvent, jUnitReporter); + children.add(picklePickleRunner); + } } catch (InitializationError e) { throw new CucumberException("Failed to create scenario runner", e); } diff --git a/junit/src/main/java/cucumber/runtime/junit/JUnitOptions.java b/junit/src/main/java/cucumber/runtime/junit/JUnitOptions.java index 8b24c88594..f98d38d5ae 100644 --- a/junit/src/main/java/cucumber/runtime/junit/JUnitOptions.java +++ b/junit/src/main/java/cucumber/runtime/junit/JUnitOptions.java @@ -14,6 +14,7 @@ public class JUnitOptions { private boolean allowStartedIgnored = false; private boolean filenameCompatibleNames = false; + private boolean stepNotifications = true; /** * Create a new instance from a list of options, for example: @@ -38,7 +39,9 @@ private void parse(List args) { allowStartedIgnored = !arg.startsWith("--no-"); } else if (arg.equals("--no-filename-compatible-names") || arg.equals("--filename-compatible-names")) { filenameCompatibleNames = !arg.startsWith("--no-"); - } else { + } else if (arg.equals("--no-step-notifications") || arg.equals("--step-notifications")) { + stepNotifications = !arg.startsWith("--no-"); + } else{ throw new CucumberException("Unknown option: " + arg); } } @@ -50,6 +53,9 @@ boolean allowStartedIgnored() { boolean filenameCompatibleNames() { return filenameCompatibleNames; } + public boolean stepNotifications(){ + return stepNotifications; + } private void printOptions() { loadUsageTextIfNeeded(); diff --git a/junit/src/main/java/cucumber/runtime/junit/JUnitReporter.java b/junit/src/main/java/cucumber/runtime/junit/JUnitReporter.java index 472dc2cd17..f6bb0e1f5a 100644 --- a/junit/src/main/java/cucumber/runtime/junit/JUnitReporter.java +++ b/junit/src/main/java/cucumber/runtime/junit/JUnitReporter.java @@ -6,10 +6,13 @@ import cucumber.api.event.TestStepFinished; import cucumber.api.event.TestStepStarted; import cucumber.runner.EventBus; +import cucumber.runtime.junit.PickleRunners.PickleRunner; import gherkin.pickles.PickleStep; -import org.junit.internal.runners.model.EachTestNotifier; +import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; +import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; +import org.junit.runners.model.MultipleFailureException; import static cucumber.runtime.Runtime.isPending; @@ -18,10 +21,10 @@ public class JUnitReporter { private final boolean strict; private final JUnitOptions junitOptions; - EachTestNotifier stepNotifier; // package-private for testing - private ExecutionUnitRunner executionUnitRunner; + TestNotifier stepNotifier; // package-private for testing + private PickleRunner pickleRunner; private RunNotifier runNotifier; - EachTestNotifier executionUnitNotifier; // package-private for testing + TestNotifier pickleRunnerNotifier; // package-private for testing private boolean failedStep; private boolean ignoredStep; private final EventHandler testStepStartedHandler = new EventHandler() { @@ -34,7 +37,7 @@ public void receive(TestStepStarted event) { } }; - private EventHandler testStepFinishedHandler = new EventHandler() { + private final EventHandler testStepFinishedHandler = new EventHandler() { @Override public void receive(TestStepFinished event) { @@ -54,32 +57,40 @@ public JUnitReporter(EventBus bus, boolean strict, JUnitOptions junitOption) { bus.registerHandlerFor(TestStepFinished.class, testStepFinishedHandler); } - void startExecutionUnit(ExecutionUnitRunner executionUnitRunner, RunNotifier runNotifier) { - this.executionUnitRunner = executionUnitRunner; + void startExecutionUnit(PickleRunner pickleRunner, RunNotifier runNotifier) { + this.pickleRunner = pickleRunner; this.runNotifier = runNotifier; this.stepNotifier = null; this.failedStep = false; this.ignoredStep = false; - executionUnitNotifier = new EachTestNotifier(runNotifier, executionUnitRunner.getDescription()); - executionUnitNotifier.fireTestStarted(); + pickleRunnerNotifier = new EachTestNotifier(runNotifier, pickleRunner.getDescription()); + pickleRunnerNotifier.fireTestStarted(); } void finishExecutionUnit() { if (ignoredStep && !failedStep) { - executionUnitNotifier.fireTestIgnored(); + pickleRunnerNotifier.fireTestIgnored(); } - executionUnitNotifier.fireTestFinished(); + pickleRunnerNotifier.fireTestFinished(); } void handleStepStarted(PickleStep step) { - Description description = executionUnitRunner.describeChild(step); - stepNotifier = new EachTestNotifier(runNotifier, description); + if (stepNotifications()) { + Description description = pickleRunner.describeChild(step); + stepNotifier = new EachTestNotifier(runNotifier, description); + } else { + stepNotifier = new NoTestNotifier(); + } if (junitOptions.allowStartedIgnored()) { stepNotifier.fireTestStarted(); } } + boolean stepNotifications() { + return junitOptions.stepNotifications(); + } + void handleStepResult(Result result) { Throwable error = result.getError(); if (result.is(Result.Type.SKIPPED)) { @@ -99,14 +110,14 @@ void handleStepResult(Result result) { } if (error != null) { failedStep = true; - executionUnitNotifier.addFailure(error); + pickleRunnerNotifier.addFailure(error); } } } void handleHookResult(Result result) { if (result.is(Result.Type.FAILED) || (strict && isPending(result.getError()))) { - executionUnitNotifier.addFailure(result.getError()); + pickleRunnerNotifier.addFailure(result.getError()); } else if (isPending(result.getError())) { ignoredStep = true; } @@ -141,6 +152,84 @@ private void addFailure(Result result) { } failedStep = true; stepNotifier.addFailure(error); - executionUnitNotifier.addFailure(error); + pickleRunnerNotifier.addFailure(error); + } + + private interface TestNotifier { + + void fireTestStarted(); + + void addFailure(Throwable error); + + void fireTestIgnored(); + + void fireTestFinished(); + } + + + private static final class NoTestNotifier implements TestNotifier { + + @Override + public void fireTestStarted() { + // Does nothing + } + + @Override + public void addFailure(Throwable error) { + // Does nothing + } + + @Override + public void fireTestIgnored() { + // Does nothing + } + + @Override + public void fireTestFinished() { + // Does nothing + } + } + + static class EachTestNotifier implements TestNotifier { + private final RunNotifier notifier; + + private final Description description; + + EachTestNotifier(RunNotifier notifier, Description description) { + this.notifier = notifier; + this.description = description; + } + + public void addFailure(Throwable targetException) { + if (targetException instanceof MultipleFailureException) { + addMultipleFailureException((MultipleFailureException) targetException); + } else if (targetException instanceof AssumptionViolatedException) { + addFailedAssumption((AssumptionViolatedException) targetException); + } else { + notifier.fireTestFailure(new Failure(description, targetException)); + } + } + + private void addMultipleFailureException(MultipleFailureException mfe) { + for (Throwable each : mfe.getFailures()) { + addFailure(each); + } + } + + private void addFailedAssumption(AssumptionViolatedException e) { + notifier.fireTestAssumptionFailed(new Failure(description, e)); + } + + public void fireTestFinished() { + notifier.fireTestFinished(description); + } + + public void fireTestStarted() { + notifier.fireTestStarted(description); + } + + public void fireTestIgnored() { + notifier.fireTestIgnored(description); + } } } diff --git a/junit/src/main/java/cucumber/runtime/junit/PickleRunners.java b/junit/src/main/java/cucumber/runtime/junit/PickleRunners.java new file mode 100644 index 0000000000..e6b5c4b6de --- /dev/null +++ b/junit/src/main/java/cucumber/runtime/junit/PickleRunners.java @@ -0,0 +1,227 @@ +package cucumber.runtime.junit; + +import cucumber.runner.Runner; +import gherkin.events.PickleEvent; +import gherkin.pickles.PickleStep; +import org.junit.runner.Description; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.ParentRunner; +import org.junit.runners.model.InitializationError; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + + +class PickleRunners { + + interface PickleRunner { + void run(RunNotifier notifier); + + Description getDescription(); + + Description describeChild(PickleStep step); + + } + + static PickleRunner withStepDescriptions(cucumber.runner.Runner runner, PickleEvent pickleEvent, JUnitReporter jUnitReporter) throws InitializationError { + return new WithStepDescriptions(runner, pickleEvent, jUnitReporter); + } + + + static PickleRunner withNoStepDescriptions(cucumber.runner.Runner runner, PickleEvent pickleEvent, JUnitReporter jUnitReporter) throws InitializationError { + return new NoStepDescriptions(runner, pickleEvent, jUnitReporter); + } + + + static class WithStepDescriptions extends ParentRunner implements PickleRunner { + private final Runner runner; + private final PickleEvent pickleEvent; + private final JUnitReporter jUnitReporter; + private final Map stepDescriptions = new HashMap(); + private Description description; + + WithStepDescriptions(Runner runner, PickleEvent pickleEvent, JUnitReporter jUnitReporter) throws InitializationError { + super(null); + this.runner = runner; + this.pickleEvent = pickleEvent; + this.jUnitReporter = jUnitReporter; + } + + @Override + protected List getChildren() { + return pickleEvent.pickle.getSteps(); + } + + @Override + public String getName() { + return getPickleName(pickleEvent, jUnitReporter.useFilenameCompatibleNames()); + } + + @Override + public Description getDescription() { + if (description == null) { + description = Description.createSuiteDescription(getName(), new PickleId(pickleEvent)); + for (PickleStep step : getChildren()) { + description.addChild(describeChild(step)); + } + } + return description; + } + + @Override + public Description describeChild(PickleStep step) { + Description description = stepDescriptions.get(step); + if (description == null) { + String testName; + if (jUnitReporter.useFilenameCompatibleNames()) { + testName = makeNameFilenameCompatible(step.getText()); + } else { + testName = step.getText(); + } + description = Description.createTestDescription(getName(), testName, new PickleStepId(pickleEvent, step)); + stepDescriptions.put(step, description); + } + return description; + } + + @Override + public void run(final RunNotifier notifier) { + jUnitReporter.startExecutionUnit(this, notifier); + // This causes runChild to never be called, which seems OK. + runner.runPickle(pickleEvent); + jUnitReporter.finishExecutionUnit(); + } + + @Override + protected void runChild(PickleStep step, RunNotifier notifier) { + // The way we override run(RunNotifier) causes this method to never be called. + // Instead it happens via cucumberScenario.run(jUnitReporter, jUnitReporter, runtime); + throw new UnsupportedOperationException(); + } + + } + + + static final class NoStepDescriptions implements PickleRunner { + private final cucumber.runner.Runner runner; + private final PickleEvent pickleEvent; + private final JUnitReporter jUnitReporter; + private Description description; + + NoStepDescriptions(cucumber.runner.Runner runner, PickleEvent pickleEvent, JUnitReporter jUnitReporter) throws InitializationError { + this.runner = runner; + this.pickleEvent = pickleEvent; + this.jUnitReporter = jUnitReporter; + } + + @Override + public Description getDescription() { + if (description == null) { + // While we are presenting this to junit as a test we use the createSuiteDescription + // method to create the description. This grants us full control over the display name. + // while Description.createTestDescription would concat a class and method name. + String name = getPickleName(pickleEvent, jUnitReporter.useFilenameCompatibleNames()); + description = Description.createSuiteDescription(name, new PickleId(pickleEvent)); + } + return description; + } + + @Override + public Description describeChild(PickleStep step) { + throw new UnsupportedOperationException("This pickle runner does not wish to describe its children"); + } + + @Override + public void run(final RunNotifier notifier) { + jUnitReporter.startExecutionUnit(this, notifier); + runner.runPickle(pickleEvent); + jUnitReporter.finishExecutionUnit(); + } + } + + private static String getPickleName(PickleEvent pickleEvent, boolean useFilenameCompatibleNames) { + final String name = pickleEvent.pickle.getName(); + if (name.isEmpty()) { + return "EMPTY_NAME"; + } + + if (useFilenameCompatibleNames) { + return makeNameFilenameCompatible(name); + } + + return name; + } + + private static String makeNameFilenameCompatible(String name) { + return name.replaceAll("[^A-Za-z0-9_]", "_"); + } + + private static final class PickleId implements Serializable { + private static final long serialVersionUID = 1L; + private final String uri; + private int pickleLine; + + PickleId(PickleEvent pickleEvent) { + this.uri = pickleEvent.uri; + this.pickleLine = pickleEvent.pickle.getLocations().get(0).getLine(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PickleId that = (PickleId) o; + return pickleLine == that.pickleLine && uri.equals(that.uri); + } + + @Override + public int hashCode() { + int result = uri.hashCode(); + result = 31 * result + pickleLine; + return result; + } + + @Override + public String toString() { + return uri + ":" + pickleLine; + } + } + + private static final class PickleStepId implements Serializable { + private static final long serialVersionUID = 1L; + private final String uri; + private final int pickleLine; + private int pickleStepLine; + + PickleStepId(PickleEvent pickleEvent, PickleStep pickleStepLine) { + this.uri = pickleEvent.uri; + this.pickleLine = pickleEvent.pickle.getLocations().get(0).getLine(); + this.pickleStepLine = pickleStepLine.getLocations().get(0).getLine(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PickleStepId that = (PickleStepId) o; + return pickleLine == that.pickleLine && pickleStepLine == that.pickleStepLine && uri.equals(that.uri); + } + + @Override + public int hashCode() { + int result = pickleLine; + result = 31 * result + uri.hashCode(); + result = 31 * result + pickleStepLine; + return result; + } + + @Override + public String toString() { + return uri + ":" + pickleLine + ":" + pickleStepLine; + } + } + +} diff --git a/junit/src/main/resources/cucumber/api/junit/OPTIONS.txt b/junit/src/main/resources/cucumber/api/junit/OPTIONS.txt index a144010688..67cd5f2320 100644 --- a/junit/src/main/resources/cucumber/api/junit/OPTIONS.txt +++ b/junit/src/main/resources/cucumber/api/junit/OPTIONS.txt @@ -13,4 +13,9 @@ JUnit Options: names for certain can be used as file names. For instance gradle will use these names in the file names of the JUnit xml report files. - + --[no-]step-notifications By default steps are included in notifications + and descriptions. When interacting with cucumber + in an IDE it is nice to see the step executions. + However presenting step executions as tests to + various reporters such as surefire results in + strange test counts and weird reports. \ No newline at end of file diff --git a/junit/src/test/java/cucumber/runtime/junit/CucumberTest.java b/junit/src/test/java/cucumber/runtime/junit/CucumberTest.java index 4e0f009d81..24b6900afa 100644 --- a/junit/src/test/java/cucumber/runtime/junit/CucumberTest.java +++ b/junit/src/test/java/cucumber/runtime/junit/CucumberTest.java @@ -42,14 +42,14 @@ public void ensureOriginalDirectory() { @Test public void finds_features_based_on_implicit_package() throws IOException, InitializationError { Cucumber cucumber = new Cucumber(ImplicitFeatureAndGluePath.class); - assertEquals(3, cucumber.getChildren().size()); + assertEquals(2, cucumber.getChildren().size()); assertEquals("Feature: FA", cucumber.getChildren().get(0).getName()); } @Test public void finds_features_based_on_explicit_root_package() throws IOException, InitializationError { Cucumber cucumber = new Cucumber(ExplicitFeaturePath.class); - assertEquals(3, cucumber.getChildren().size()); + assertEquals(2, cucumber.getChildren().size()); assertEquals("Feature: FA", cucumber.getChildren().get(0).getName()); } diff --git a/junit/src/test/java/cucumber/runtime/junit/FeatureRunnerTest.java b/junit/src/test/java/cucumber/runtime/junit/FeatureRunnerTest.java index 4a71c2aeaa..a8a6827403 100644 --- a/junit/src/test/java/cucumber/runtime/junit/FeatureRunnerTest.java +++ b/junit/src/test/java/cucumber/runtime/junit/FeatureRunnerTest.java @@ -7,7 +7,6 @@ import cucumber.runtime.RuntimeOptions; import cucumber.runtime.io.ClasspathResourceLoader; import cucumber.runtime.model.CucumberFeature; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.notification.RunNotifier; @@ -15,7 +14,7 @@ import org.mockito.ArgumentMatcher; import org.mockito.InOrder; -import java.util.Collections; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -99,13 +98,19 @@ private RunNotifier runFeatureWithNotifier(CucumberFeature cucumberFeature) thro return notifier; } - private FeatureRunner createFeatureRunner(CucumberFeature cucumberFeature) throws InitializationError { + private FeatureRunner createFeatureRunner(CucumberFeature cucumberFeature, String... options) throws InitializationError { + JUnitOptions junitOption = new JUnitOptions(Arrays.asList(options)); + return createFeatureRunner(cucumberFeature, junitOption); + } + + + private FeatureRunner createFeatureRunner(CucumberFeature cucumberFeature, JUnitOptions junitOption) throws InitializationError { final RuntimeOptions runtimeOptions = new RuntimeOptions("-p null"); final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader(classLoader); final RuntimeGlue glue = mock(RuntimeGlue.class); final Runtime runtime = new Runtime(resourceLoader, classLoader, asList(mock(Backend.class)), runtimeOptions, new TimeService.Stub(0l), glue); - return new FeatureRunner(cucumberFeature, runtime, new JUnitReporter(runtime.getEventBus(), false, new JUnitOptions(Collections.emptyList()))); + return new FeatureRunner(cucumberFeature, runtime, new JUnitReporter(runtime.getEventBus(), false, junitOption)); } @@ -139,9 +144,43 @@ public void shouldPopulateDescriptionsWithStableUniqueIds() throws Exception { } + @Test + public void shouldNotCreateStepDescriptions() throws Exception { + CucumberFeature cucumberFeature = TestPickleBuilder.parseFeature("path/test.feature", "" + + "Feature: feature name\n" + + " Background:\n" + + " Given background step\n" + + " Scenario: A\n" + + " Then scenario name\n" + + " Scenario: B\n" + + " Then scenario name\n" + + " Scenario Outline: C\n" + + " Then scenario \n" + + " Examples:\n" + + " | name |\n" + + " | C |\n" + + " | D |\n" + + " | E |\n" + + ); + + FeatureRunner runner = createFeatureRunner(cucumberFeature, "--no-step-notifications"); + + Description feature = runner.getDescription(); + Description scenarioA = feature.getChildren().get(0); + assertTrue(scenarioA.getChildren().isEmpty()); + Description scenarioB = feature.getChildren().get(1); + assertTrue(scenarioB.getChildren().isEmpty()); + Description scenarioC0 = feature.getChildren().get(2); + assertTrue(scenarioC0.getChildren().isEmpty()); + Description scenarioC1 = feature.getChildren().get(3); + assertTrue(scenarioC1.getChildren().isEmpty()); + Description scenarioC2 = feature.getChildren().get(4); + assertTrue(scenarioC2.getChildren().isEmpty()); + } + private static void assertDescriptionIsUnique(Description description, Set descriptions) { - // Note, JUnit uses the the serializable parameter (in this case the step) - // as the unique id when comparing Descriptions + // Note: JUnit uses the the serializable parameter as the unique id when comparing Descriptions assertTrue(descriptions.add(description)); for (Description each : description.getChildren()) { assertDescriptionIsUnique(each, descriptions); @@ -154,21 +193,19 @@ private static void assertDescriptionIsPredictable(Description description, Set< assertDescriptionIsPredictable(each, descriptions); } } -} -class DescriptionMatcher extends ArgumentMatcher { - private String name; + private static final class DescriptionMatcher extends ArgumentMatcher { + private String name; - public DescriptionMatcher(String name) { - this.name = name; - } + DescriptionMatcher(String name) { + this.name = name; + } - @Override - public boolean matches(Object argument) { - if (argument instanceof Description && ((Description) argument).getDisplayName().equals(name)) { - return true; + @Override + public boolean matches(Object argument) { + return argument instanceof Description && ((Description) argument).getDisplayName().equals(name); } - return false; + } +} -} \ No newline at end of file diff --git a/junit/src/test/java/cucumber/runtime/junit/JUnitReporterTest.java b/junit/src/test/java/cucumber/runtime/junit/JUnitReporterTest.java index 1a49496662..76069d9238 100644 --- a/junit/src/test/java/cucumber/runtime/junit/JUnitReporterTest.java +++ b/junit/src/test/java/cucumber/runtime/junit/JUnitReporterTest.java @@ -3,9 +3,9 @@ import cucumber.api.PendingException; import cucumber.api.Result; import cucumber.runner.EventBus; +import cucumber.runtime.junit.PickleRunners.PickleRunner; import gherkin.pickles.PickleStep; import org.junit.Test; -import org.junit.internal.runners.model.EachTestNotifier; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; @@ -34,14 +34,14 @@ public void match_allow_started_ignored() { createAllowStartedIgnoredReporter(); PickleStep runnerStep = mockStep(); Description runnerStepDescription = stepDescription(runnerStep); - ExecutionUnitRunner executionUnitRunner = mockExecutionUnitRunner(runnerSteps(runnerStep)); - when(executionUnitRunner.describeChild(runnerStep)).thenReturn(runnerStepDescription); + PickleRunner pickleRunner = mockPickleRunner(runnerSteps(runnerStep)); + when(pickleRunner.describeChild(runnerStep)).thenReturn(runnerStepDescription); runNotifier = mock(RunNotifier.class); - jUnitReporter.startExecutionUnit(executionUnitRunner, runNotifier); + jUnitReporter.startExecutionUnit(pickleRunner, runNotifier); jUnitReporter.handleStepStarted(runnerStep); - verify(runNotifier).fireTestStarted(executionUnitRunner.getDescription()); + verify(runNotifier).fireTestStarted(pickleRunner.getDescription()); verify(runNotifier).fireTestStarted(runnerStepDescription); } @@ -68,7 +68,7 @@ public void resultWithError() { @Test public void result_with_undefined_step_non_strict() { createNonStrictReporter(); - EachTestNotifier stepNotifier = mock(EachTestNotifier.class); + JUnitReporter.EachTestNotifier stepNotifier = mock(JUnitReporter.EachTestNotifier.class); jUnitReporter.stepNotifier = stepNotifier; jUnitReporter.handleStepResult(mockResult(Result.Type.UNDEFINED)); @@ -83,21 +83,21 @@ public void result_with_undefined_step_non_strict() { public void result_with_undefined_step_strict() { createStrictReporter(); createDefaultRunNotifier(); - EachTestNotifier stepNotifier = mock(EachTestNotifier.class); + JUnitReporter.EachTestNotifier stepNotifier = mock(JUnitReporter.EachTestNotifier.class); jUnitReporter.stepNotifier = stepNotifier; - EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class); - jUnitReporter.executionUnitNotifier = executionUnitNotifier; + JUnitReporter.EachTestNotifier pickleRunnerNotifier = mock(JUnitReporter.EachTestNotifier.class); + jUnitReporter.pickleRunnerNotifier = pickleRunnerNotifier; jUnitReporter.handleStepResult(mockResult(Result.Type.UNDEFINED)); verify(stepNotifier, times(1)).fireTestStarted(); verify(stepNotifier, times(1)).fireTestFinished(); verifyAddFailureWithPendingException(stepNotifier); - verifyAddFailureWithPendingException(executionUnitNotifier); + verifyAddFailureWithPendingException(pickleRunnerNotifier); verify(stepNotifier, times(0)).fireTestIgnored(); } - private void verifyAddFailureWithPendingException(EachTestNotifier stepNotifier) { + private void verifyAddFailureWithPendingException(JUnitReporter.EachTestNotifier stepNotifier) { ArgumentCaptor captor = ArgumentCaptor.forClass(Throwable.class); verify(stepNotifier).addFailure(captor.capture()); Throwable error = captor.getValue(); @@ -110,7 +110,7 @@ public void result_with_pending_step_non_strict() { Result result = mock(Result.class); when(result.getError()).thenReturn(new PendingException()); - EachTestNotifier stepNotifier = mock(EachTestNotifier.class); + JUnitReporter.EachTestNotifier stepNotifier = mock(JUnitReporter.EachTestNotifier.class); jUnitReporter.stepNotifier = stepNotifier; jUnitReporter.handleStepResult(result); @@ -128,17 +128,17 @@ public void result_with_pending_step_strict() { Result result = mock(Result.class); when(result.getError()).thenReturn(new PendingException()); - EachTestNotifier stepNotifier = mock(EachTestNotifier.class); + JUnitReporter.EachTestNotifier stepNotifier = mock(JUnitReporter.EachTestNotifier.class); jUnitReporter.stepNotifier = stepNotifier; - EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class); - jUnitReporter.executionUnitNotifier = executionUnitNotifier; + JUnitReporter.EachTestNotifier pickleRunnerNotifier = mock(JUnitReporter.EachTestNotifier.class); + jUnitReporter.pickleRunnerNotifier = pickleRunnerNotifier; jUnitReporter.handleStepResult(result); verify(stepNotifier, times(1)).fireTestStarted(); verify(stepNotifier, times(1)).fireTestFinished(); verifyAddFailureWithPendingException(stepNotifier); - verifyAddFailureWithPendingException(executionUnitNotifier); + verifyAddFailureWithPendingException(pickleRunnerNotifier); verify(stepNotifier, times(0)).fireTestIgnored(); } @@ -147,7 +147,7 @@ public void result_without_error_non_strict() { createNonStrictReporter(); Result result = mock(Result.class); - EachTestNotifier stepNotifier = mock(EachTestNotifier.class); + JUnitReporter.EachTestNotifier stepNotifier = mock(JUnitReporter.EachTestNotifier.class); jUnitReporter.stepNotifier = stepNotifier; jUnitReporter.handleStepResult(result); @@ -163,7 +163,7 @@ public void result_without_error_strict() { createStrictReporter(); Result result = mock(Result.class); - EachTestNotifier stepNotifier = mock(EachTestNotifier.class); + JUnitReporter.EachTestNotifier stepNotifier = mock(JUnitReporter.EachTestNotifier.class); jUnitReporter.stepNotifier = stepNotifier; jUnitReporter.handleStepResult(result); @@ -179,7 +179,7 @@ public void result_without_error_allow_stared_ignored() { createAllowStartedIgnoredReporter(); Result result = mock(Result.class); - EachTestNotifier stepNotifier = mock(EachTestNotifier.class); + JUnitReporter.EachTestNotifier stepNotifier = mock(JUnitReporter.EachTestNotifier.class); jUnitReporter.stepNotifier = stepNotifier; jUnitReporter.handleStepResult(result); @@ -197,12 +197,12 @@ public void hook_with_pending_exception_strict() { Result result = mockResult(Result.Type.PENDING); when(result.getError()).thenReturn(new PendingException()); - EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class); - jUnitReporter.executionUnitNotifier = executionUnitNotifier; + JUnitReporter.EachTestNotifier pickleRunnerNotifier = mock(JUnitReporter.EachTestNotifier.class); + jUnitReporter.pickleRunnerNotifier = pickleRunnerNotifier; jUnitReporter.handleHookResult(result); - verifyAddFailureWithPendingException(executionUnitNotifier); + verifyAddFailureWithPendingException(pickleRunnerNotifier); } @Test @@ -212,13 +212,13 @@ public void hook_with_pending_exception_non_strict() { Result result = mockResult(Result.Type.PENDING); when(result.getError()).thenReturn(new PendingException()); - EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class); - jUnitReporter.executionUnitNotifier = executionUnitNotifier; + JUnitReporter.EachTestNotifier pickleRunnerNotifier = mock(JUnitReporter.EachTestNotifier.class); + jUnitReporter.pickleRunnerNotifier = pickleRunnerNotifier; jUnitReporter.handleHookResult(result); jUnitReporter.finishExecutionUnit(); - verify(executionUnitNotifier).fireTestIgnored(); + verify(pickleRunnerNotifier).fireTestIgnored(); } @Test @@ -231,26 +231,26 @@ public void failed_step_and_after_with_pending_exception_non_strict() { Result hookResult = mockResult(Result.Type.PENDING); when(hookResult.getError()).thenReturn(new PendingException()); - EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class); - jUnitReporter.executionUnitNotifier = executionUnitNotifier; + JUnitReporter.EachTestNotifier pickleRunnerNotifier = mock(JUnitReporter.EachTestNotifier.class); + jUnitReporter.pickleRunnerNotifier = pickleRunnerNotifier; jUnitReporter.handleStepResult(stepResult); jUnitReporter.handleHookResult(hookResult); jUnitReporter.finishExecutionUnit(); - verify(executionUnitNotifier, times(0)).fireTestIgnored(); + verify(pickleRunnerNotifier, times(0)).fireTestIgnored(); } @Test public void creates_step_notifier_with_step_from_execution_unit_runner() throws Exception { PickleStep runnerStep = mockStep("Step Name"); Description runnerStepDescription = stepDescription(runnerStep); - ExecutionUnitRunner executionUnitRunner = mockExecutionUnitRunner(runnerSteps(runnerStep)); - when(executionUnitRunner.describeChild(runnerStep)).thenReturn(runnerStepDescription); + PickleRunner pickleRunner = mockPickleRunner(runnerSteps(runnerStep)); + when(pickleRunner.describeChild(runnerStep)).thenReturn(runnerStepDescription); RunNotifier notifier = mock(RunNotifier.class); jUnitReporter = new JUnitReporter(mock(EventBus.class), false, new JUnitOptions(Collections.emptyList())); - jUnitReporter.startExecutionUnit(executionUnitRunner, notifier); + jUnitReporter.startExecutionUnit(pickleRunner, notifier); jUnitReporter.handleStepStarted(runnerStep); jUnitReporter.handleStepResult(mockResult()); @@ -269,10 +269,10 @@ private Result mockResult(Result.Type status) { return result; } - private ExecutionUnitRunner mockExecutionUnitRunner(List runnerSteps) { - ExecutionUnitRunner executionUnitRunner = mock(ExecutionUnitRunner.class); - when(executionUnitRunner.getDescription()).thenReturn(mock(Description.class)); - return executionUnitRunner; + private PickleRunner mockPickleRunner(List runnerSteps) { + PickleRunner pickleRunner = mock(PickleRunner.class); + when(pickleRunner.getDescription()).thenReturn(mock(Description.class)); + return pickleRunner; } private List runnerSteps(PickleStep step) { @@ -302,9 +302,9 @@ private void createDefaultRunNotifier() { private void createRunNotifier(Description description) { runNotifier = mock(RunNotifier.class); - ExecutionUnitRunner executionUnitRunner = mock(ExecutionUnitRunner.class); - when(executionUnitRunner.getDescription()).thenReturn(description); - jUnitReporter.startExecutionUnit(executionUnitRunner, runNotifier); + PickleRunner pickleRunner = mock(PickleRunner.class); + when(pickleRunner.getDescription()).thenReturn(description); + jUnitReporter.startExecutionUnit(pickleRunner, runNotifier); } private void createStrictReporter() { diff --git a/junit/src/test/java/cucumber/runtime/junit/PickleRunnerWithNoStepDescriptionsTest.java b/junit/src/test/java/cucumber/runtime/junit/PickleRunnerWithNoStepDescriptionsTest.java new file mode 100644 index 0000000000..06c611378d --- /dev/null +++ b/junit/src/test/java/cucumber/runtime/junit/PickleRunnerWithNoStepDescriptionsTest.java @@ -0,0 +1,73 @@ +package cucumber.runtime.junit; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import cucumber.runner.EventBus; +import cucumber.runner.Runner; +import cucumber.runtime.junit.PickleRunners.PickleRunner; +import gherkin.events.PickleEvent; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class PickleRunnerWithNoStepDescriptionsTest { + + @Test + public void shouldUseScenarioNameForDisplayName() throws Exception { + List pickles = TestPickleBuilder.pickleEventsFromFeature("featurePath", "" + + "Feature: feature name\n" + + " Scenario: scenario name\n" + + " Then it works\n"); + + PickleRunner runner = PickleRunners.withNoStepDescriptions( + mock(Runner.class), + pickles.get(0), + createStandardJUnitReporter() + ); + + assertEquals("scenario name", runner.getDescription().getDisplayName()); + } + + @Test + public void shouldUseScenarioNameForDescriptionDisplayName() throws Exception { + List pickles = TestPickleBuilder.pickleEventsFromFeature("featurePath", "" + + "Feature: feature name\n" + + " Scenario: scenario name\n" + + " Then it works\n"); + + PickleRunner runner = PickleRunners.withNoStepDescriptions( + mock(Runner.class), + pickles.get(0), + createStandardJUnitReporter() + ); + + assertEquals("scenario name", runner.getDescription().getDisplayName()); + } + + @Test + public void shouldConvertTextFromFeatureFileForNamesWithFilenameCompatibleNameOption() throws Exception { + List pickles = TestPickleBuilder.pickleEventsFromFeature("featurePath", "" + + "Feature: feature name\n" + + " Scenario: scenario name\n" + + " Then it works\n"); + + PickleRunner runner = PickleRunners.withNoStepDescriptions( + mock(Runner.class), + pickles.get(0), + createJUnitReporterWithOption("--filename-compatible-names") + ); + + assertEquals("scenario_name", runner.getDescription().getDisplayName()); + } + + private JUnitReporter createStandardJUnitReporter() { + return new JUnitReporter(mock(EventBus.class), false, new JUnitOptions(Collections.emptyList())); + } + + private JUnitReporter createJUnitReporterWithOption(String option) { + return new JUnitReporter(mock(EventBus.class), false, new JUnitOptions(Arrays.asList(option))); + } +} diff --git a/junit/src/test/java/cucumber/runtime/junit/ExecutionUnitRunnerTest.java b/junit/src/test/java/cucumber/runtime/junit/PickleRunnerWithStepDescriptionsTest.java similarity index 60% rename from junit/src/test/java/cucumber/runtime/junit/ExecutionUnitRunnerTest.java rename to junit/src/test/java/cucumber/runtime/junit/PickleRunnerWithStepDescriptionsTest.java index c2b6a4bd7f..753d7059f9 100644 --- a/junit/src/test/java/cucumber/runtime/junit/ExecutionUnitRunnerTest.java +++ b/junit/src/test/java/cucumber/runtime/junit/PickleRunnerWithStepDescriptionsTest.java @@ -1,8 +1,13 @@ package cucumber.runtime.junit; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.Mockito.mock; + import cucumber.runner.EventBus; import cucumber.runner.Runner; -import cucumber.runtime.io.ClasspathResourceLoader; +import cucumber.runtime.junit.PickleRunners.PickleRunner; +import cucumber.runtime.junit.PickleRunners.WithStepDescriptions; import cucumber.runtime.model.CucumberFeature; import gherkin.events.PickleEvent; import gherkin.pickles.Compiler; @@ -16,27 +21,29 @@ import java.util.Collections; import java.util.List; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.mockito.Mockito.mock; - -public class ExecutionUnitRunnerTest { +public class PickleRunnerWithStepDescriptionsTest { @Test public void shouldAssignUnequalDescriptionsToDifferentOccurrencesOfSameStepInAScenario() throws Exception { - List features = CucumberFeature.load( - new ClasspathResourceLoader(this.getClass().getClassLoader()), - asList("cucumber/runtime/junit/fb.feature"), - null + CucumberFeature features = TestPickleBuilder.parseFeature("path/test.feature", "" + + "Feature: FB\n" + + "# Scenario with same step occurring twice\n" + + "\n" + + " Scenario: SB\n" + + " When foo\n" + + " Then bar\n" + + "\n" + + " When foo\n" + + " Then baz\n" ); + Compiler compiler = new Compiler(); List pickleEvents = new ArrayList(); - for (Pickle pickle : compiler.compile(features.get(0).getGherkinFeature())) { - pickleEvents.add(new PickleEvent(features.get(0).getPath(), pickle)); + for (Pickle pickle : compiler.compile(features.getGherkinFeature())) { + pickleEvents.add(new PickleEvent(features.getPath(), pickle)); }; - ExecutionUnitRunner runner = new ExecutionUnitRunner( + WithStepDescriptions runner = (WithStepDescriptions) PickleRunners.withStepDescriptions( mock(Runner.class), pickleEvents.get(0), createStandardJUnitReporter() @@ -58,46 +65,69 @@ public void shouldAssignUnequalDescriptionsToDifferentOccurrencesOfSameStepInASc @Test public void shouldIncludeScenarioNameAsClassNameInStepDescriptions() throws Exception { - List features = CucumberFeature.load( - new ClasspathResourceLoader(this.getClass().getClassLoader()), - asList("cucumber/runtime/junit/feature_with_same_steps_in_different_scenarios.feature"), - null + CucumberFeature features = TestPickleBuilder.parseFeature("path/test.feature", "" + + "Feature: In cucumber.junit\n" + + " Scenario: first\n" + + " When step\n" + + " Then another step\n" + + "\n" + + " Scenario: second\n" + + " When step\n" + + " Then another step\n" ); + Compiler compiler = new Compiler(); List pickleEvents = new ArrayList(); - for (Pickle pickle : compiler.compile(features.get(0).getGherkinFeature())) { - pickleEvents.add(new PickleEvent(features.get(0).getPath(), pickle)); - }; + for (Pickle pickle : compiler.compile(features.getGherkinFeature())) { + pickleEvents.add(new PickleEvent(features.getPath(), pickle)); + } - ExecutionUnitRunner runner = new ExecutionUnitRunner( + PickleRunner runner = PickleRunners.withStepDescriptions( mock(Runner.class), pickleEvents.get(0), createStandardJUnitReporter() ); // fish out the data from runner - PickleStep step = runner.getChildren().get(0); Description runnerDescription = runner.getDescription(); Description stepDescription = runnerDescription.getChildren().get(0); - assertEquals("description includes scenario name as class name", runner.getName(), stepDescription.getClassName()); - assertEquals("description includes step keyword and name as method name", step.getText(), stepDescription.getMethodName()); + assertEquals("description includes scenario name as class name", "first", stepDescription.getClassName()); + assertEquals("description includes step keyword and name as method name", "step", stepDescription.getMethodName()); + assertEquals("description includes scenario and step name in display name", "step(first)", stepDescription.getDisplayName()); + } @Test - public void shouldUseScenarioNameForRunnerName() throws Exception { + public void shouldUseScenarioNameForDisplayName() throws Exception { List pickles = TestPickleBuilder.pickleEventsFromFeature("featurePath", "" + "Feature: feature name\n" + " Scenario: scenario name\n" + " Then it works\n"); - ExecutionUnitRunner runner = new ExecutionUnitRunner( + PickleRunner runner = PickleRunners.withStepDescriptions( mock(Runner.class), pickles.get(0), createStandardJUnitReporter() ); - assertEquals("scenario name", runner.getName()); + assertEquals("scenario name", runner.getDescription().getDisplayName()); + } + + @Test + public void shouldUseScenarioNameForDescriptionDisplayName() throws Exception { + List pickles = TestPickleBuilder.pickleEventsFromFeature("featurePath", "" + + "Feature: feature name\n" + + " Scenario: scenario name\n" + + " Then it works\n"); + + PickleRunner runner = PickleRunners.withNoStepDescriptions( + mock(Runner.class), + pickles.get(0), + createStandardJUnitReporter() + ); + + assertEquals("scenario name", runner.getDescription().getDisplayName()); } @Test @@ -107,7 +137,7 @@ public void shouldUseStepKeyworkAndNameForChildName() throws Exception { " Scenario: scenario name\n" + " Then it works\n"); - ExecutionUnitRunner runner = new ExecutionUnitRunner( + PickleRunner runner = PickleRunners.withStepDescriptions( mock(Runner.class), pickleEvents.get(0), createStandardJUnitReporter() @@ -123,13 +153,14 @@ public void shouldConvertTextFromFeatureFileForNamesWithFilenameCompatibleNameOp " Scenario: scenario name\n" + " Then it works\n"); - ExecutionUnitRunner runner = new ExecutionUnitRunner( + PickleRunner runner = PickleRunners.withStepDescriptions( mock(Runner.class), pickles.get(0), createJUnitReporterWithOption("--filename-compatible-names") ); - assertEquals("scenario_name", runner.getName()); + assertEquals("scenario_name", runner.getDescription().getDisplayName()); + assertEquals("scenario_name", runner.getDescription().getChildren().get(0).getClassName()); assertEquals("it_works", runner.getDescription().getChildren().get(0).getMethodName()); } diff --git a/junit/src/test/java/cucumber/runtime/junit/RunCukesTestNoStepNotifications.java b/junit/src/test/java/cucumber/runtime/junit/RunCukesTestNoStepNotifications.java new file mode 100644 index 0000000000..eb0a4f77d4 --- /dev/null +++ b/junit/src/test/java/cucumber/runtime/junit/RunCukesTestNoStepNotifications.java @@ -0,0 +1,10 @@ +package cucumber.runtime.junit; + +import cucumber.api.CucumberOptions; +import cucumber.api.junit.Cucumber; +import org.junit.runner.RunWith; + +@RunWith(Cucumber.class) +@CucumberOptions(junit = "--no-step-notifications") +public class RunCukesTestNoStepNotifications { +} diff --git a/junit/src/test/java/cucumber/runtime/junit/SanityTest.java b/junit/src/test/java/cucumber/runtime/junit/SanityTest.java index 1863492dd2..0af9c28be6 100644 --- a/junit/src/test/java/cucumber/runtime/junit/SanityTest.java +++ b/junit/src/test/java/cucumber/runtime/junit/SanityTest.java @@ -12,4 +12,9 @@ public void reports_events_correctly_with_cucumber_runner() { public void reports_events_correctly_with_junit_runner() { SanityChecker.run(RunCukesTest.class); } + + @Test + public void reports_events_correctly_with_no_step_notifications() { + SanityChecker.run(RunCukesTestNoStepNotifications.class); + } } diff --git a/junit/src/test/resources/cucumber/runtime/junit/feature_with_same_steps_in_different_scenarios.feature b/junit/src/test/resources/cucumber/runtime/junit/feature_with_same_steps_in_different_scenarios.feature deleted file mode 100644 index 9b15d8fbb4..0000000000 --- a/junit/src/test/resources/cucumber/runtime/junit/feature_with_same_steps_in_different_scenarios.feature +++ /dev/null @@ -1,8 +0,0 @@ -Feature: In cucumber.junit - Scenario: first - When step - Then another step - - Scenario: second - When step - Then another step