Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented rerun formatter #524

Merged
merged 1 commit into from
Aug 15, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class FormatterFactory {
put("progress", ProgressFormatter.class);
put("json", JSONFormatter.class);
put("usage", UsageFormatter.class);
put("rerun", RerunFormatter.class);
}};
private static final Pattern FORMATTER_WITH_FILE_PATTERN = Pattern.compile("([^:]+):(.*)");
private Appendable defaultOut = new OutputStreamWriter(System.out) {
Expand Down
137 changes: 137 additions & 0 deletions core/src/main/java/cucumber/runtime/formatter/RerunFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package cucumber.runtime.formatter;

import gherkin.formatter.Formatter;
import gherkin.formatter.NiceAppendable;
import gherkin.formatter.Reporter;
import gherkin.formatter.model.*;

import java.util.*;


/**
* Formatter for reporting all failed features and print their locations
* Failed means: (failed, undefined, pending) test result
*/
class RerunFormatter implements Formatter, Reporter {

private final NiceAppendable out;

private String featureLocation;

private Step step;

private Map<String, LinkedHashSet<Integer>> featureAndFailedLinesMapping = new HashMap<String, LinkedHashSet<Integer>>();


public RerunFormatter(Appendable out) {
this.out = new NiceAppendable(out);
}

@Override
public void uri(String uri) {
this.featureLocation = uri;
}

@Override
public void feature(Feature feature) {
}

@Override
public void background(Background background) {
}

@Override
public void scenario(Scenario scenario) {
}

@Override
public void scenarioOutline(ScenarioOutline scenarioOutline) {
}

@Override
public void examples(Examples examples) {
}

@Override
public void step(Step step) {
this.step = step;
}

@Override
public void eof() {
}

@Override
public void syntaxError(String state, String event, List<String> legalEvents, String uri, Integer line) {
}

@Override
public void done() {
reportFailedSteps();
}

private void reportFailedSteps() {
Set<Map.Entry<String, LinkedHashSet<Integer>>> entries = featureAndFailedLinesMapping.entrySet();
boolean firstFeature = true;
for (Map.Entry<String, LinkedHashSet<Integer>> entry : entries) {
if (entry.getValue().size() > 0) {
if (!firstFeature) {
out.append(" ");
}
out.append(entry.getKey());
firstFeature = false;
for (Integer line : entry.getValue()) {
out.append(":").append(line.toString());
}
}
}
}

@Override
public void close() {
this.out.close();
}

@Override
public void before(Match match, Result result) {

}

@Override
public void result(Result result) {
if (isTestFailed(result)) {
recordTestFailed();
}
}

private boolean isTestFailed(Result result) {
String status = result.getStatus();
return Result.FAILED.equals(status) || Result.UNDEFINED.getStatus().equals(status) || "pending".equals(status);
}

private void recordTestFailed() {
LinkedHashSet<Integer> failedSteps = this.featureAndFailedLinesMapping.get(featureLocation);
if (failedSteps == null) {
failedSteps = new LinkedHashSet<Integer>();
this.featureAndFailedLinesMapping.put(featureLocation, failedSteps);
}

failedSteps.add(step.getLine());
}

@Override
public void after(Match match, Result result) {
}

@Override
public void match(Match match) {
}

@Override
public void embedding(String mimeType, byte[] data) {
}

@Override
public void write(String text) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package cucumber.runtime.java.formatter;


import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* Just a dummy glue code which helps for testing
*/
public class DummyGlueCode {

@Given("^The glue code faker is up$")
public void The_glue_code_faker_is_up() throws Throwable {
}

@cucumber.api.java.en.When("^activity is triggered$")
public void activity_is_tirggered() throws Throwable {
}

@cucumber.api.java.en.Then("^forcing test to fail$")
public void forcing_test_to_fail() throws Throwable {
fail("Designed to fail");
}

@Then("^force to pass$")
public void force_to_pass() throws Throwable {
}

@Then("^forcing the dummy glue code to (\\d)$")
public void forcing_the_dummy_glue_code_to_booleanCode(int code) throws Throwable {
assertTrue(code == 1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cucumber.runtime.java.formatter;

import cucumber.api.junit.Cucumber;
import gherkin.util.FixJava;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.notification.RunNotifier;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class RerunFormatterTest {

public static final String TARGET_SAMPLE_OUTPUT = "target/sample.txt";

@Before
public void setUp() throws Exception {
File file = new File(TARGET_SAMPLE_OUTPUT);
if (file.exists()) {
assertTrue("Formatter output must be cleaned up", file.delete());
}
}

@Test
public void testRerunFormatterIsReportingFailedFeatures() throws Exception {
new Cucumber(RerunFormatterSampleFeatures.class).run(new RunNotifier());
assertOnOutput("cucumber/runtime/java/formatter/exaple-table.feature:6 cucumber/runtime/java/formatter/rerun_failure.feature:8:14:20 cucumber/runtime/java/formatter/rerun_failure2.feature:11");
}

private void assertOnOutput(String expectedMessage) {

try {
String output = FixJava.readReader(new FileReader(TARGET_SAMPLE_OUTPUT));
assertEquals(expectedMessage, output);
} catch (FileNotFoundException e) {
fail("Rerun formatter output not available " + e.getMessage());
}
}

@Test
public void testRerunFormatterNotReportingSuccessTest() throws Exception {
new Cucumber(RerunFormatterPassingFeature.class).run(new RunNotifier());
assertProducedOutputIsEmpty();
}

private void assertProducedOutputIsEmpty() {
assertTrue(new File(TARGET_SAMPLE_OUTPUT).exists());
assertEquals(0, new File(TARGET_SAMPLE_OUTPUT).length());
}

@Cucumber.Options(format = "rerun:target/sample.txt", features = {"classpath:cucumber/runtime/java/formatter"})
private class RerunFormatterSampleFeatures {

}

@Cucumber.Options(format = "rerun:target/sample.txt", features = {"classpath:cucumber/runtime/java/formatter/passing.feature"})
private class RerunFormatterPassingFeature {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Feature: Sample example table

Scenario Outline: Testing rerun formatter
Given The glue code faker is up
When activity is triggered
Then forcing the dummy glue code to <booleanCode>

Examples:
|booleanCode|
|0 |
|0 |
|1 |
|1 |
|0 |


Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Feature: Testing sample rerun formatter

Scenario: Testing two number addition

Given The glue code faker is up
When activity is triggered
Then force to pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#line numbers are referenced in tests, please keep as it is
Feature: Testing sample rerun formatter

Scenario: Testing two number addition

Given The glue code faker is up
When activity is triggered
Then forcing test to fail

Scenario: Testing two number addition

Given The glue code faker is up
When activity is triggered
Then forcing test to fail

Scenario: Testing two number addition

Given The glue code faker is up
When activity is triggered
Then forcing test to fail
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#line numbers are referenced in tests, please keep as it is
Feature: Testing sample rerun formatter

Scenario: Testing two number addition




Given The glue code faker is up
When activity is triggered
Then forcing test to fail