Skip to content

Commit

Permalink
[Core] Do not use TestHelper in TeamCityPluginTest
Browse files Browse the repository at this point in the history
  • Loading branch information
mpkorstanje committed Sep 4, 2020
1 parent db89dc2 commit fc56498
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 103 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
package io.cucumber.core.backend;

import io.cucumber.core.backend.HookDefinition;
import io.cucumber.core.backend.TestCaseState;
import java.util.function.Consumer;

public class StubHookDefinition implements HookDefinition {

private final RuntimeException exception;
private final Consumer<TestCaseState> action;

public StubHookDefinition(RuntimeException exception, Consumer<TestCaseState> action) {
this.exception = exception;
this.action = action;
}

public StubHookDefinition() {
this(null);
this(null, null);
}

public StubHookDefinition(Consumer<TestCaseState> action) {
this(null, action);
}

public StubHookDefinition(RuntimeException exception) {
this.exception = exception;
this(exception, null);
}

@Override
public void execute(TestCaseState state) {
if (exception == null) {
return;
if(action != null){
action.accept(state);
}
if (exception != null) {
throw exception;
}
throw exception;
}

@Override
Expand Down
6 changes: 6 additions & 0 deletions core/src/test/java/io/cucumber/core/plugin/StubException.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.cucumber.core.plugin;

import java.io.PrintStream;
import java.io.PrintWriter;

class StubException extends RuntimeException {
Expand All @@ -20,4 +21,9 @@ public void printStackTrace(PrintWriter printWriter) {
printWriter.print(stacktrace);
}

@Override
public void printStackTrace(PrintStream printStream) {
printStream.print(stacktrace);
}

}
233 changes: 137 additions & 96 deletions core/src/test/java/io/cucumber/core/plugin/TeamCityPluginTest.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,34 @@
package io.cucumber.core.plugin;

import io.cucumber.core.backend.StubHookDefinition;
import io.cucumber.core.backend.StubStepDefinition;
import io.cucumber.core.backend.TestCaseState;
import io.cucumber.core.feature.TestFeatureParser;
import io.cucumber.core.gherkin.Feature;
import io.cucumber.core.runner.TestHelper;
import io.cucumber.plugin.event.Result;
import io.cucumber.core.runtime.Runtime;
import io.cucumber.core.runtime.StubBackendSupplier;
import io.cucumber.core.runtime.StubFeatureSupplier;
import io.cucumber.core.runtime.TimeServiceEventBus;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.mockito.stubbing.Answer;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static io.cucumber.core.runner.TestHelper.createAttachHookAction;
import static io.cucumber.core.runner.TestHelper.createWriteHookAction;
import static io.cucumber.core.runner.TestHelper.hookEntry;
import static io.cucumber.core.runner.TestHelper.result;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.containsString;
import java.util.UUID;

import static io.cucumber.core.plugin.BytesContainsString.bytesContainsString;
import static java.time.Clock.fixed;
import static java.time.Instant.EPOCH;
import static java.time.ZoneId.of;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;

@DisabledOnOs(OS.WINDOWS)
class TeamCityPluginTest {

private final List<Feature> features = new ArrayList<>();
private final Map<String, Result> stepsToResult = new HashMap<>();
private final Map<String, String> stepsToLocation = new HashMap<>();
private final List<SimpleEntry<String, Result>> hooks = new ArrayList<>();
private final List<String> hookLocations = new ArrayList<>();
private final List<Answer<Object>> hookActions = new ArrayList<>();
private final String location = new File("").toURI().toString();

@Test
void should_handle_scenario_outline() {
Feature feature = TestFeatureParser.parse("path/test.feature", "" +
Expand All @@ -48,14 +40,23 @@ void should_handle_scenario_outline() {
" | name | arg |\n" +
" | name 1 | second |\n" +
" | name 2 | third |\n");
features.add(feature);
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");
stepsToLocation.put("second step", "com.example.StepDefinition.secondStep()");
stepsToLocation.put("third step", "com.example.StepDefinition.thirdStep()");

String formatterOutput = runFeaturesWithFormatter();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier(
new StubStepDefinition("first step"),
new StubStepDefinition("second step"),
new StubStepDefinition("third step")
))
.build()
.run();

assertThat(formatterOutput, containsString("" +
String location = new File("").toURI().toString();

String expected = "" +
"##teamcity[enteredTheMatrix timestamp = '1970-01-01T12:00:00.000+0000']\n" +
"##teamcity[testSuiteStarted timestamp = '1970-01-01T12:00:00.000+0000' name = 'Cucumber']\n" +
"##teamcity[customProgressStatus testsCategory = 'Scenarios' count = '0' timestamp = '1970-01-01T12:00:00.000+0000']\n"
Expand Down Expand Up @@ -97,26 +98,9 @@ void should_handle_scenario_outline() {
"##teamcity[testSuiteFinished timestamp = '1970-01-01T12:00:00.000+0000' name = 'examples name']\n" +
"##teamcity[testSuiteFinished timestamp = '1970-01-01T12:00:00.000+0000' name = '<name>']\n" +
"##teamcity[testSuiteFinished timestamp = '1970-01-01T12:00:00.000+0000' name = 'feature name']\n" +
"##teamcity[testSuiteFinished timestamp = '1970-01-01T12:00:00.000+0000' name = 'Cucumber']\n"));
}
"##teamcity[testSuiteFinished timestamp = '1970-01-01T12:00:00.000+0000' name = 'Cucumber']\n";

private String runFeaturesWithFormatter() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(byteArrayOutputStream);
final TeamCityPlugin formatter = new TeamCityPlugin(printStream);

TestHelper.builder()
.withFormatterUnderTest(formatter)
.withFeatures(features)
.withStepsToResult(stepsToResult)
.withStepsToLocation(stepsToLocation)
.withHooks(hooks)
.withHookLocations(hookLocations)
.withHookActions(hookActions)
.build()
.run();

return new String(byteArrayOutputStream.toByteArray(), UTF_8);
assertThat(out, bytesContainsString(expected));
}

@Test
Expand All @@ -125,18 +109,22 @@ void should_handle_nameless_attach_events() {
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n");
features.add(feature);
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");
stepsToResult.put("first step", result("passed"));
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");

hooks.add(hookEntry("before", result("passed")));
hookLocations.add("Hooks.before_hook_3()");
hookActions.add(createAttachHookAction("A message".getBytes(), "text/plain"));

String formatterOutput = runFeaturesWithFormatter();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier(
singletonList(new StubHookDefinition(
(TestCaseState state) -> state.attach("A message", "text/plain", null))),
singletonList(new StubStepDefinition("first step")),
emptyList()
))
.build()
.run();

assertThat(formatterOutput, containsString("" +
assertThat(out, bytesContainsString("" +
"##teamcity[message text='Embed event: |[text/plain 9 bytes|]|n' status='NORMAL']\n"));
}

Expand All @@ -146,18 +134,21 @@ void should_handle_write_events() {
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n");
features.add(feature);
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");
stepsToResult.put("first step", result("passed"));
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");

hooks.add(hookEntry("before", result("passed")));
hookLocations.add("Hooks.before_hook_1()");
hookActions.add(createWriteHookAction("A message"));

String formatterOutput = runFeaturesWithFormatter();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier(
singletonList(new StubHookDefinition((TestCaseState state) -> state.log("A message"))),
singletonList(new StubStepDefinition("first step")),
emptyList()
))
.build()
.run();

assertThat(formatterOutput, containsString("" +
assertThat(out, bytesContainsString("" +
"##teamcity[message text='Write event:|nA message|n' status='NORMAL']\n"));
}

Expand All @@ -167,18 +158,22 @@ void should_handle_attach_events() {
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n");
features.add(feature);
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");
stepsToResult.put("first step", result("passed"));
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");

hooks.add(hookEntry("before", result("passed")));
hookLocations.add("Hooks.before_hook_3()");
hookActions.add(createAttachHookAction("A message".getBytes(), "text/plain", "message.txt"));

String formatterOutput = runFeaturesWithFormatter();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier(
singletonList(new StubHookDefinition(
(TestCaseState state) -> state.attach("A message", "text/plain", "message.txt"))),
singletonList(new StubStepDefinition("first step")),
emptyList()
))
.build()
.run();

assertThat(formatterOutput, containsString("" +
assertThat(out, bytesContainsString("" +
"##teamcity[message text='Embed event: message.txt |[text/plain 9 bytes|]|n' status='NORMAL']\n"));
}

Expand All @@ -188,13 +183,19 @@ void should_print_error_message_for_failed_steps() {
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n");
features.add(feature);
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");
stepsToResult.put("first step", result("failed"));

String formatterOutput = runFeaturesWithFormatter();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier(
new StubStepDefinition("first step", new StubException("Step failed", "the stack trace")))
)
.build()
.run();

assertThat(formatterOutput, containsString("" +
assertThat(out, bytesContainsString("" +
"##teamcity[testFailed timestamp = '1970-01-01T12:00:00.000+0000' duration = '0' message = 'Step failed' details = 'the stack trace' name = 'first step']\n"));
}

Expand All @@ -204,13 +205,17 @@ void should_print_error_message_for_undefined_steps() {
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n");
features.add(feature);
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");
stepsToResult.put("first step", result("undefined"));

String formatterOutput = runFeaturesWithFormatter();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier())
.build()
.run();

assertThat(formatterOutput, containsString("" +
assertThat(out, bytesContainsString("" +
"##teamcity[testFailed timestamp = '1970-01-01T12:00:00.000+0000' duration = '0' message = 'Step undefined' details = 'You can implement missing steps with the snippets below:|n|n' name = 'first step']\n"));
}

Expand All @@ -220,18 +225,54 @@ void should_print_error_message_for_before_hooks() {
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n");
features.add(feature);
stepsToLocation.put("first step", "com.example.StepDefinition.firstStep()");
stepsToResult.put("first step", result("passed"));
hooks.add(hookEntry("before", result("failed")));
hookLocations.add("com.example.HookDefinition.beforeHook()");

String formatterOutput = runFeaturesWithFormatter();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier(
singletonList(new StubHookDefinition(new StubException("Step failed", "the stack trace"))),
singletonList(new StubStepDefinition("first step")),
emptyList()
))
.build()
.run();

assertThat(formatterOutput, containsString("" +
"##teamcity[testStarted timestamp = '1970-01-01T12:00:00.000+0000' locationHint = 'java:test://com.example.HookDefinition/beforeHook' captureStandardOutput = 'true' name = 'Before']\n"
assertThat(out, bytesContainsString("" +
"##teamcity[testStarted timestamp = '1970-01-01T12:00:00.000+0000' locationHint = '{stubbed location with details}' captureStandardOutput = 'true' name = 'Before']\n"
+
"##teamcity[testFailed timestamp = '1970-01-01T12:00:00.000+0000' duration = '0' message = 'Step failed' details = 'the stack trace' name = 'Before']"));
}

@Test
void should_print_location_hint_for_hooks() {
Feature feature = TestFeatureParser.parse("path/test.feature", "" +
"Feature: feature name\n" +
" Scenario: scenario name\n" +
" Given first step\n");

ByteArrayOutputStream out = new ByteArrayOutputStream();
Runtime.builder()
.withFeatureSupplier(new StubFeatureSupplier(feature))
.withAdditionalPlugins(new TeamCityPlugin(new PrintStream(out)))
.withEventBus(new TimeServiceEventBus(fixed(EPOCH, of("UTC")), UUID::randomUUID))
.withBackendSupplier(new StubBackendSupplier(
singletonList(new StubHookDefinition() {

@Override
public String getLocation() {
return "com.example.HookDefinition.beforeHook()";
}
}),
singletonList(new StubStepDefinition("first step")),
emptyList()
))
.build()
.run();

assertThat(out, bytesContainsString("" +
"##teamcity[testStarted timestamp = '1970-01-01T12:00:00.000+0000' locationHint = 'java:test://com.example.HookDefinition/beforeHook' captureStandardOutput = 'true' name = 'Before']\n"));
}

}

0 comments on commit fc56498

Please sign in to comment.