Skip to content

Commit

Permalink
[TestNG] Updated testng for the use of Gherkin v4.0.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
brasmusson committed Sep 4, 2016
1 parent a632c27 commit ecfc554
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 244 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ public CucumberFeature getCucumberFeature() {

@Override
public String toString() {
return cucumberFeature.getGherkinFeature().getName();
return cucumberFeature.getGherkinFeature().getFeature().getName();
}
}
57 changes: 17 additions & 40 deletions testng/src/main/java/cucumber/api/testng/FeatureResultListener.java
Original file line number Diff line number Diff line change
@@ -1,52 +1,35 @@
package cucumber.api.testng;

import cucumber.runtime.CucumberException;
import gherkin.formatter.Reporter;
import gherkin.formatter.model.Match;
import gherkin.formatter.model.Result;
import cucumber.api.Result;
import cucumber.api.event.EventHandler;
import cucumber.api.event.EventPublisher;
import cucumber.api.event.TestStepFinished;
import cucumber.api.formatter.Formatter;

public class FeatureResultListener implements Reporter {
public class FeatureResultListener implements Formatter {
static final String PENDING_STATUS = "pending";
static final String UNDEFINED_MESSAGE = "There are undefined steps";
static final String PENDING_MESSAGE = "There are pending steps";
private Reporter reporter;
private boolean strict;
private Throwable error = null;
private final EventHandler<TestStepFinished> testStepFinishedHandler = new EventHandler<TestStepFinished>() {
@Override
public void receive(TestStepFinished event) {
collectError(event.result);
}
};

public FeatureResultListener(Reporter reporter, boolean strict) {
this.reporter = reporter;
public FeatureResultListener(boolean strict) {
this.strict = strict;
}

@Override
public void after(Match match, Result result) {
collectError(result);
reporter.after(match, result);
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepFinished.class, testStepFinishedHandler);
}

@Override
public void before(Match match, Result result) {
collectError(result);
reporter.before(match, result);
}

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

@Override
public void match(Match match) {
reporter.match(match);
}

@Override
public void result(Result result) {
collectError(result);
reporter.result(result);
}

private void collectError(Result result) {
void collectError(Result result) {
if (result.getStatus().equals(Result.FAILED)) {
if (error == null || isUndefinedError(error) || isPendingError(error)) {
error = result.getError();
Expand All @@ -55,7 +38,7 @@ private void collectError(Result result) {
if (error == null || isUndefinedError(error)) {
error = new CucumberException(PENDING_MESSAGE);
}
} else if (result.getStatus().equals(Result.UNDEFINED.getStatus()) && strict) {
} else if (result.getStatus().equals(Result.UNDEFINED) && strict) {
if (error == null) {
error = new CucumberException(UNDEFINED_MESSAGE);
}
Expand All @@ -70,11 +53,6 @@ private boolean isUndefinedError(Throwable error) {
return (error instanceof CucumberException) && error.getMessage().equals(UNDEFINED_MESSAGE);
}

@Override
public void write(String text) {
reporter.write(text);
}

public boolean isPassed() {
return error == null;
}
Expand All @@ -86,5 +64,4 @@ public Throwable getFirstError() {
public void startFeature() {
error = null;
}

}
28 changes: 12 additions & 16 deletions testng/src/main/java/cucumber/api/testng/TestNGCucumberRunner.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cucumber.api.testng;

import cucumber.api.event.TestRunFinished;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.CucumberException;
import cucumber.runtime.Runtime;
Expand All @@ -9,7 +10,6 @@
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import cucumber.runtime.model.CucumberFeature;
import gherkin.formatter.Formatter;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -19,6 +19,7 @@
*/
public class TestNGCucumberRunner {
private Runtime runtime;
private TestNgReporter reporter;
private RuntimeOptions runtimeOptions;
private ResourceLoader resourceLoader;
private FeatureResultListener resultListener;
Expand All @@ -36,21 +37,21 @@ public TestNGCucumberRunner(Class clazz) {
RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(clazz);
runtimeOptions = runtimeOptionsFactory.create();

TestNgReporter reporter = new TestNgReporter(System.out);
reporter = new TestNgReporter(System.out);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
resultListener = new FeatureResultListener(runtimeOptions.reporter(classLoader), runtimeOptions.isStrict());
resultListener = new FeatureResultListener(runtimeOptions.isStrict());
runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
reporter.setEventPublisher(runtime.getEventBus());
resultListener.setEventPublisher(runtime.getEventBus());
}

/**
* Run the Cucumber features
*/
public void runCukes() {
for (CucumberFeature cucumberFeature : getFeatures()) {
cucumberFeature.run(
runtimeOptions.formatter(classLoader),
resultListener,
runtime);
reporter.uri(cucumberFeature.getPath());
runtime.runFeature(cucumberFeature);
}
finish();
if (!resultListener.isPassed()) {
Expand All @@ -60,29 +61,24 @@ public void runCukes() {

public void runCucumber(CucumberFeature cucumberFeature) {
resultListener.startFeature();
cucumberFeature.run(
runtimeOptions.formatter(classLoader),
resultListener,
runtime);
reporter.uri(cucumberFeature.getPath());
runtime.runFeature(cucumberFeature);

if (!resultListener.isPassed()) {
throw new CucumberException(resultListener.getFirstError());
}
}

public void finish() {
Formatter formatter = runtimeOptions.formatter(classLoader);

formatter.done();
formatter.close();
runtime.getEventBus().send(new TestRunFinished());
runtime.printSummary();
}

/**
* @return List of detected cucumber features
*/
public List<CucumberFeature> getFeatures() {
return runtimeOptions.cucumberFeatures(resourceLoader);
return runtimeOptions.cucumberFeatures(resourceLoader, runtime.getEventBus());
}

/**
Expand Down
141 changes: 35 additions & 106 deletions testng/src/main/java/cucumber/api/testng/TestNgReporter.java
Original file line number Diff line number Diff line change
@@ -1,103 +1,56 @@
package cucumber.api.testng;

import cucumber.runtime.Utils;
import gherkin.formatter.Formatter;
import gherkin.formatter.NiceAppendable;
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 gherkin.pickles.PickleStep;
import cucumber.api.Result;
import cucumber.api.event.EventHandler;
import cucumber.api.event.EventPublisher;
import cucumber.api.event.TestRunFinished;
import cucumber.api.event.TestStepFinished;
import cucumber.api.formatter.Formatter;
import cucumber.api.formatter.NiceAppendable;
import org.testng.ITestResult;

import java.util.LinkedList;
import java.util.List;

import static org.testng.Reporter.getCurrentTestResult;
import static org.testng.Reporter.log;

public class TestNgReporter implements Formatter, Reporter {
public class TestNgReporter implements Formatter {
private final NiceAppendable out;
private final LinkedList<Step> steps = new LinkedList<Step>();
private final EventHandler<TestStepFinished> testStepFinishedHandler = new EventHandler<TestStepFinished>() {
@Override
public void receive(TestStepFinished event) {
if (!event.testStep.isHook()) {
result(event.testStep.getStepText(), event.result);
}
}
};
private EventHandler<TestRunFinished> runFinishHandler = new EventHandler<TestRunFinished>() {

@Override
public void receive(TestRunFinished event) {
out.close();
}
};


public TestNgReporter(Appendable appendable) {
out = new NiceAppendable(appendable);
}

@Override
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepFinished.class, testStepFinishedHandler);
publisher.registerHandlerFor(TestRunFinished.class, runFinishHandler);
}

public void uri(String uri) {
// TODO: find an appropriate keyword
String keyword = "Feature File";
logDiv(keyword, uri, "featureFile");
}

@Override
public void feature(Feature feature) {
logDiv(feature.getKeyword(), feature.getName(), "feature");
}

@Override
public void background(Background background) {
}

@Override
public void scenario(Scenario scenario) {
logDiv(scenario.getKeyword(), scenario.getName(), "scenario");
}

@Override
public void scenarioOutline(ScenarioOutline scenarioOutline) {
logDiv(scenarioOutline.getKeyword(), scenarioOutline.getName(), "scenarioOutline");
}

@Override
public void examples(Examples examples) {
}

@Override
public void step(Step step) {
steps.add(step);
}

@Override
public void eof() {
}

@Override
public void syntaxError(String s, String s2, List<String> strings, String s3, Integer integer) {
}

@Override
public void done() {
steps.clear();
}

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

@Override
public void startOfScenarioLifeCycle(Scenario scenario) {
// NoOp
}

@Override
public void endOfScenarioLifeCycle(Scenario scenario) {
// NoOp
}

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

@Override
public void result(Result result) {
logResult(result);
private void result(String stepText, Result result) {
logResult(stepText, result);

if (Result.FAILED.equals(result.getStatus())) {
ITestResult tr = getCurrentTestResult();
Expand All @@ -114,19 +67,11 @@ public void result(Result result) {
}
}

private void logResult(Result result) {
private void logResult(String stepText, Result result) {
String timing = computeTiming(result);

Step step;
if (steps.isEmpty()) {
step = new Step(null, "MISMATCH BETWEEN STEPS AND RESULTS", "", 0, null, null);
} else {
step = steps.pop();
}

String format = "%s %s (%s%s)";
String message = String.format(format, step.getKeyword(),
step.getName(), result.getStatus(), timing);
String format = "%s (%s%s)";
String message = String.format(format, stepText, result.getStatus(), timing);

logDiv(message, "result");
}
Expand All @@ -143,22 +88,6 @@ private String computeTiming(Result result) {
return timing;
}

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

@Override
public void write(String s) {
}

@Override
public void match(Match match) {
}

@Override
public void embedding(String s, byte[] bytes) {
}

private void logDiv(String message, String cssClassName) {
String format = "<div \"%s\">%s</div>";
String output = String.format(format, cssClassName, Utils.htmlEscape(message));
Expand Down
Loading

0 comments on commit ecfc554

Please sign in to comment.