package cucumber.runtime.junit;
import cucumber.api.PendingException;
import cucumber.runtime.CucumberException;
import gherkin.formatter.Formatter;
import gherkin.formatter.Reporter;
import gherkin.formatter.model.Background;
import gherkin.formatter.model.Examples;
import gherkin.formatter.model.Feature;
import gherkin.formatter.model.Match;
import gherkin.formatter.model.Result;
import gherkin.formatter.model.Scenario;
import gherkin.formatter.model.ScenarioOutline;
import gherkin.formatter.model.Step;
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;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers;
import java.util.ArrayList;
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.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class JUnitReporterTest {
private JUnitReporter jUnitReporter;
private RunNotifier runNotifier;
@Test
public void match_allow_stared_ignored() {
createAllowStartedIgnoredReporter();
Step runnerStep = mockStep();
Description runnerStepDescription = stepDescription(runnerStep);
ExecutionUnitRunner executionUnitRunner = mockExecutionUnitRunner(runnerSteps(runnerStep));
when(executionUnitRunner.describeChild(runnerStep)).thenReturn(runnerStepDescription);
runNotifier = mock(RunNotifier.class);
jUnitReporter.startExecutionUnit(executionUnitRunner, runNotifier);
jUnitReporter.startOfScenarioLifeCycle(mock(Scenario.class));
jUnitReporter.step(runnerStep);
jUnitReporter.match(mock(Match.class));
verify(runNotifier).fireTestStarted(executionUnitRunner.getDescription());
verify(runNotifier).fireTestStarted(runnerStepDescription);
}
@Test
public void resultWithError() {
createNonStrictReporter();
Result result = mock(Result.class);
Throwable exception = mock(Throwable.class);
when(result.getError()).thenReturn(exception);
Description description = mock(Description.class);
createRunNotifier(description);
jUnitReporter.result(result);
ArgumentCaptor<Failure> failureArgumentCaptor = ArgumentCaptor.forClass(Failure.class);
verify(runNotifier).fireTestFailure(failureArgumentCaptor.capture());
Failure failure = failureArgumentCaptor.getValue();
assertEquals(description, failure.getDescription());
assertEquals(exception, failure.getException());
}
@Test
public void result_with_undefined_step_non_strict() {
createNonStrictReporter();
EachTestNotifier stepNotifier = mock(EachTestNotifier.class);
jUnitReporter.stepNotifier = stepNotifier;
jUnitReporter.result(Result.UNDEFINED);
verify(stepNotifier, times(0)).fireTestStarted();
verify(stepNotifier, times(0)).fireTestFinished();
verify(stepNotifier, times(0)).addFailure(Matchers.<Throwable>any(Throwable.class));
verify(stepNotifier).fireTestIgnored();
}
@Test
public void result_with_undefined_step_strict() {
createStrictReporter();
createDefaultRunNotifier();
EachTestNotifier stepNotifier = mock(EachTestNotifier.class);
jUnitReporter.stepNotifier = stepNotifier;
EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class);
jUnitReporter.executionUnitNotifier = executionUnitNotifier;
jUnitReporter.result(Result.UNDEFINED);
verify(stepNotifier, times(1)).fireTestStarted();
verify(stepNotifier, times(1)).fireTestFinished();
verifyAddFailureWithPendingException(stepNotifier);
verifyAddFailureWithPendingException(executionUnitNotifier);
verify(stepNotifier, times(0)).fireTestIgnored();
}
private void verifyAddFailureWithPendingException(EachTestNotifier stepNotifier) {
ArgumentCaptor<Throwable> captor = ArgumentCaptor.forClass(Throwable.class);
verify(stepNotifier).addFailure(captor.capture());
Throwable error = captor.getValue();
assertTrue(error instanceof PendingException);
}
@Test
public void result_with_pending_step_non_strict() {
createNonStrictReporter();
Result result = mock(Result.class);
when(result.getError()).thenReturn(new PendingException());
EachTestNotifier stepNotifier = mock(EachTestNotifier.class);
jUnitReporter.stepNotifier = stepNotifier;
jUnitReporter.result(result);
verify(stepNotifier, times(0)).fireTestStarted();
verify(stepNotifier, times(0)).fireTestFinished();
verify(stepNotifier, times(0)).addFailure(Matchers.<Throwable>any(Throwable.class));
verify(stepNotifier).fireTestIgnored();
}
@Test
public void result_with_pending_step_strict() {
createStrictReporter();
createDefaultRunNotifier();
Result result = mock(Result.class);
when(result.getError()).thenReturn(new PendingException());
EachTestNotifier stepNotifier = mock(EachTestNotifier.class);
jUnitReporter.stepNotifier = stepNotifier;
EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class);
jUnitReporter.executionUnitNotifier = executionUnitNotifier;
jUnitReporter.result(result);
verify(stepNotifier, times(1)).fireTestStarted();
verify(stepNotifier, times(1)).fireTestFinished();
verifyAddFailureWithPendingException(stepNotifier);
verifyAddFailureWithPendingException(executionUnitNotifier);
verify(stepNotifier, times(0)).fireTestIgnored();
}
@Test
public void result_without_error_non_strict() {
createNonStrictReporter();
Result result = mock(Result.class);
EachTestNotifier stepNotifier = mock(EachTestNotifier.class);
jUnitReporter.stepNotifier = stepNotifier;
jUnitReporter.result(result);
verify(stepNotifier).fireTestStarted();
verify(stepNotifier).fireTestFinished();
verify(stepNotifier, times(0)).addFailure(Matchers.<Throwable>any(Throwable.class));
verify(stepNotifier, times(0)).fireTestIgnored();
}
@Test
public void result_without_error_strict() {
createStrictReporter();
Result result = mock(Result.class);
EachTestNotifier stepNotifier = mock(EachTestNotifier.class);
jUnitReporter.stepNotifier = stepNotifier;
jUnitReporter.result(result);
verify(stepNotifier).fireTestStarted();
verify(stepNotifier).fireTestFinished();
verify(stepNotifier, times(0)).addFailure(Matchers.<Throwable>any(Throwable.class));
verify(stepNotifier, times(0)).fireTestIgnored();
}
@Test
public void result_without_error_allow_stared_ignored() {
createAllowStartedIgnoredReporter();
Result result = mock(Result.class);
EachTestNotifier stepNotifier = mock(EachTestNotifier.class);
jUnitReporter.stepNotifier = stepNotifier;
jUnitReporter.result(result);
verify(stepNotifier, times(0)).fireTestStarted();
verify(stepNotifier).fireTestFinished();
verify(stepNotifier, times(0)).addFailure(Matchers.<Throwable>any(Throwable.class));
verify(stepNotifier, times(0)).fireTestIgnored();
}
@Test
public void before_with_pending_exception_strict() {
createStrictReporter();
createDefaultRunNotifier();
Result result = mock(Result.class);
Match match = mock(Match.class);
when(result.getStatus()).thenReturn("Pending");
when(result.getError()).thenReturn(new PendingException());
EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class);
jUnitReporter.executionUnitNotifier = executionUnitNotifier;
jUnitReporter.before(match, result);
verifyAddFailureWithPendingException(executionUnitNotifier);
}
@Test
public void after_with_pending_exception_non_strict() {
createNonStrictReporter();
createDefaultRunNotifier();
Result result = mock(Result.class);
Match match = mock(Match.class);
when(result.getStatus()).thenReturn("Pending");
when(result.getError()).thenReturn(new PendingException());
EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class);
jUnitReporter.executionUnitNotifier = executionUnitNotifier;
jUnitReporter.after(match, result);
jUnitReporter.finishExecutionUnit();
verify(executionUnitNotifier).fireTestIgnored();
}
@Test
public void failed_step_and_after_with_pending_exception_non_strict() {
createNonStrictReporter();
createDefaultRunNotifier();
Result stepResult = mock(Result.class);
Throwable exception = mock(Throwable.class);
when(stepResult.getError()).thenReturn(exception);
Result hookResult = mock(Result.class);
Match match = mock(Match.class);
when(hookResult.getStatus()).thenReturn("Pending");
when(hookResult.getError()).thenReturn(new PendingException());
EachTestNotifier executionUnitNotifier = mock(EachTestNotifier.class);
jUnitReporter.executionUnitNotifier = executionUnitNotifier;
jUnitReporter.result(stepResult);
jUnitReporter.after(match, hookResult);
jUnitReporter.finishExecutionUnit();
verify(executionUnitNotifier, times(0)).fireTestIgnored();
}
@Test
public void forward_calls_to_formatter_interface_methods() throws Exception {
String uri = "uri";
Feature feature = mock(Feature.class);
Background background = mock(Background.class);
ScenarioOutline scenarioOutline = mock(ScenarioOutline.class);
Examples examples = mock(Examples.class);
Scenario scenario = mock(Scenario.class);
Step step = mock(Step.class);
Formatter formatter = mock(Formatter.class);
jUnitReporter = new JUnitReporter(mock(Reporter.class), formatter, false, new JUnitOptions(Collections.<String>emptyList()));
jUnitReporter.uri(uri);
jUnitReporter.feature(feature);
jUnitReporter.scenarioOutline(scenarioOutline);
jUnitReporter.examples(examples);
jUnitReporter.startOfScenarioLifeCycle(scenario);
jUnitReporter.background(background);
jUnitReporter.scenario(scenario);
jUnitReporter.step(step);
jUnitReporter.endOfScenarioLifeCycle(scenario);
jUnitReporter.eof();
jUnitReporter.done();
jUnitReporter.close();
verify(formatter).uri(uri);
verify(formatter).feature(feature);
verify(formatter).scenarioOutline(scenarioOutline);
verify(formatter).examples(examples);
verify(formatter).startOfScenarioLifeCycle(scenario);;
verify(formatter).background(background);
verify(formatter).scenario(scenario);
verify(formatter).step(step);
verify(formatter).endOfScenarioLifeCycle(scenario);
verify(formatter).eof();
verify(formatter).done();
verify(formatter).close();
}
@Test
public void forward_calls_to_reporter_interface_methods() throws Exception {
Match match = mock(Match.class);
Result result = mockResult();
ExecutionUnitRunner executionUnitRunner = mockExecutionUnitRunner();
String mimeType = "mimeType";
byte data[] = new byte[] {1};
String text = "text";
Reporter reporter = mock(Reporter.class);
jUnitReporter = new JUnitReporter(reporter, mock(Formatter.class), false, new JUnitOptions(Collections.<String>emptyList()));
jUnitReporter.startExecutionUnit(executionUnitRunner, mock(RunNotifier.class));
jUnitReporter.startOfScenarioLifeCycle(mock(Scenario.class));
jUnitReporter.before(match, result);
jUnitReporter.step(mockStep());
jUnitReporter.match(match);
jUnitReporter.embedding(mimeType, data);
jUnitReporter.write(text);
jUnitReporter.result(result);
jUnitReporter.after(match, result);
verify(reporter).before(match, result);
verify(reporter).match(match);
verify(reporter).embedding(mimeType, data);
verify(reporter).write(text);
verify(reporter).result(result);
verify(reporter).after(match, result);
}
@Test
public void creates_step_notifier_with_step_from_execution_unit_runner() throws Exception {
Step runnerStep = mockStep("Step Name");
Description runnerStepDescription = stepDescription(runnerStep);
ExecutionUnitRunner executionUnitRunner = mockExecutionUnitRunner(runnerSteps(runnerStep));
when(executionUnitRunner.describeChild(runnerStep)).thenReturn(runnerStepDescription);
RunNotifier notifier = mock(RunNotifier.class);
jUnitReporter = new JUnitReporter(mock(Reporter.class), mock(Formatter.class), false, new JUnitOptions(Collections.<String>emptyList()));
jUnitReporter.startExecutionUnit(executionUnitRunner, notifier);
jUnitReporter.startOfScenarioLifeCycle(mock(Scenario.class));
jUnitReporter.step(mockStep("Step Name"));
jUnitReporter.match(mock(Match.class));
jUnitReporter.result(mockResult());
verify(notifier).fireTestFinished(runnerStepDescription);
}
@Test
public void throws_exception_when_runner_step_name_do_no_match_scenario_step_name() throws Exception {
Step runnerStep = mockStep("Runner Step Name");
ExecutionUnitRunner executionUnitRunner = mockExecutionUnitRunner(runnerSteps(runnerStep));
jUnitReporter = new JUnitReporter(mock(Reporter.class), mock(Formatter.class), false, new JUnitOptions(Collections.<String>emptyList()));
jUnitReporter.startExecutionUnit(executionUnitRunner, mock(RunNotifier.class));
jUnitReporter.startOfScenarioLifeCycle(mock(Scenario.class));
jUnitReporter.step(mockStep("Scenario Step Name"));
try {
jUnitReporter.match(mock(Match.class));
fail("CucumberException not thrown");
} catch (CucumberException e) {
assertEquals("Expected step: \"Scenario Step Name\" got step: \"Runner Step Name\"", e.getMessage());
} catch (Exception e) {
fail("CucumberException not thrown");
}
}
private Result mockResult() {
Result result = mock(Result.class);
when(result.getStatus()).thenReturn("passed");
return result;
}
private ExecutionUnitRunner mockExecutionUnitRunner() {
List<Step> runnerSteps = runnerSteps(mockStep());
return mockExecutionUnitRunner(runnerSteps);
}
private ExecutionUnitRunner mockExecutionUnitRunner(List<Step> runnerSteps) {
ExecutionUnitRunner executionUnitRunner = mock(ExecutionUnitRunner.class);
when(executionUnitRunner.getDescription()).thenReturn(mock(Description.class));
when(executionUnitRunner.getRunnerSteps()).thenReturn(runnerSteps);
return executionUnitRunner;
}
private List<Step> runnerSteps(Step step) {
List<Step> runnerSteps = new ArrayList<Step>();
runnerSteps.add(step);
return runnerSteps;
}
private Description stepDescription(Step runnerStep) {
return Description.createTestDescription("", "", runnerStep);
}
private Step mockStep() {
String stepName = "step name";
return mockStep(stepName);
}
private Step mockStep(String stepName) {
Step step = mock(Step.class);
when(step.getName()).thenReturn(stepName);
return step;
}
private void createDefaultRunNotifier() {
createRunNotifier(mock(Description.class));
}
private void createRunNotifier(Description description) {
runNotifier = mock(RunNotifier.class);
ExecutionUnitRunner executionUnitRunner = mock(ExecutionUnitRunner.class);
when(executionUnitRunner.getDescription()).thenReturn(description);
jUnitReporter.startExecutionUnit(executionUnitRunner, runNotifier);
}
private void createStrictReporter() {
createReporter(true, false);
}
private void createNonStrictReporter() {
createReporter(false, false);
}
private void createAllowStartedIgnoredReporter() {
createReporter(false, true);
}
private void createReporter(boolean strict, boolean allowStartedIgnored) {
Formatter formatter = mock(Formatter.class);
Reporter reporter = mock(Reporter.class);
String allowStartedIgnoredOption = allowStartedIgnored ? "--allow-started-ignored" : "--no-allow-started-ignored";
jUnitReporter = new JUnitReporter(reporter, formatter, strict, new JUnitOptions(asList(allowStartedIgnoredOption)));
}
}