Skip to content

Commit

Permalink
Merge pull request #536 from brasmusson/summary-printout
Browse files Browse the repository at this point in the history
Merge pull request #536 Print summary at the end of the run.
This fixes #195. Update the History.md.
  • Loading branch information
brasmusson committed Jul 16, 2013
2 parents 4439178 + 40a223a commit f63f6c3
Show file tree
Hide file tree
Showing 10 changed files with 572 additions and 10 deletions.
1 change: 1 addition & 0 deletions History.md
Expand Up @@ -19,6 +19,7 @@
* [Core] JUnitFormatter: Fix indentation, hook handling and support all-steps-first execution ([#556](https://github.com/cucumber/cucumber-jvm/pull/556) Björn Rasmusson)
* [Core] Make the PrettyFormatter work by revering to all-steps-first execution ([#491](https://github.com/cucumber/cucumber-jvm/issues/491), [#557](https://github.com/cucumber/cucumber-jvm/pull/557) Björn Rasmusson)
* [Core] Test case for the PrettyFormatter. ([#544](https://github.com/cucumber/cucumber-jvm/pull/544) Björn Rasmusson)
* [Core/Junit] Print summary at the end of the run. ([#195](https://github.com/cucumber/cucumber-jvm/issues/195), [#536](https://github.com/cucumber/cucumber-jvm/pull/536) Björn Rasmusson)

## [1.1.3](https://github.com/cucumber/cucumber-jvm/compare/v1.1.2...v1.1.3) (2013-03-10)

Expand Down
31 changes: 26 additions & 5 deletions core/src/main/java/cucumber/runtime/Runtime.java
Expand Up @@ -13,6 +13,7 @@
import gherkin.formatter.model.*;

import java.io.IOException;
import java.io.PrintStream;
import java.util.*;

/**
Expand All @@ -31,6 +32,7 @@ public class Runtime implements UnreportedStepExecutor {
private static final Object DUMMY_ARG = new Object();
private static final byte ERRORS = 0x1;

private final SummaryCounter summaryCounter;
final UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker();

private final Glue glue;
Expand Down Expand Up @@ -64,6 +66,7 @@ public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collectio
this.backends = backends;
this.runtimeOptions = runtimeOptions;
this.glue = optionalGlue != null ? optionalGlue : new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader));
this.summaryCounter = new SummaryCounter(runtimeOptions.isMonochrome());

for (Backend backend : backends) {
backend.loadGlue(glue, runtimeOptions.getGlue());
Expand All @@ -89,8 +92,8 @@ public void run() {
Formatter formatter = runtimeOptions.formatter(classLoader);

formatter.done();
printSummary();
formatter.close();
printSummary();
}

private void run(CucumberFeature cucumberFeature) {
Expand All @@ -115,6 +118,7 @@ public void buildBackendWorlds(Reporter reporter, Set<Tag> tags) {
}

public void disposeBackendWorlds() {
summaryCounter.addScenario(scenarioResult.getStatus());
for (Backend backend : backends) {
backend.disposeWorld();
}
Expand Down Expand Up @@ -197,7 +201,7 @@ private void runHookIfTagsMatch(HookDefinition hook, Reporter reporter, Set<Tag>
} finally {
long duration = System.nanoTime() - start;
Result result = new Result(status, duration, error, DUMMY_ARG);
scenarioResult.add(result);
addHookToCounterAndResult(result);
if (isBefore) {
reporter.before(match, result);
} else {
Expand Down Expand Up @@ -234,7 +238,9 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
match = glue.stepDefinitionMatch(uri, step, i18n);
} catch (AmbiguousStepDefinitionsException e) {
reporter.match(e.getMatches().get(0));
reporter.result(new Result(Result.FAILED, 0L, e, DUMMY_ARG));
Result result = new Result(Result.FAILED, 0L, e, DUMMY_ARG);
reporter.result(result);
addStepToCounterAndResult(result);
addError(e);
skipNextStep = true;
return;
Expand All @@ -245,6 +251,7 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
} else {
reporter.match(Match.UNDEFINED);
reporter.result(Result.UNDEFINED);
addStepToCounterAndResult(Result.UNDEFINED);
skipNextStep = true;
return;
}
Expand All @@ -254,7 +261,7 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
}

if (skipNextStep) {
scenarioResult.add(Result.SKIPPED);
addStepToCounterAndResult(Result.SKIPPED);
reporter.result(Result.SKIPPED);
} else {
String status = Result.PASSED;
Expand All @@ -270,7 +277,7 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
} finally {
long duration = System.nanoTime() - start;
Result result = new Result(status, duration, error, DUMMY_ARG);
scenarioResult.add(result);
addStepToCounterAndResult(result);
reporter.result(result);
}
}
Expand All @@ -286,4 +293,18 @@ public static boolean isPending(Throwable t) {
public void writeStepdefsJson() throws IOException {
glue.writeStepdefsJson(runtimeOptions.getFeaturePaths(), runtimeOptions.getDotCucumber());
}

public void printSummary(PrintStream out) {
summaryCounter.printSummary(out);
}

private void addStepToCounterAndResult(Result result) {
scenarioResult.add(result);
summaryCounter.addStep(result);
}

private void addHookToCounterAndResult(Result result) {
scenarioResult.add(result);
summaryCounter.addHookTime(result.getDuration());
}
}
4 changes: 4 additions & 0 deletions core/src/main/java/cucumber/runtime/RuntimeOptions.java
Expand Up @@ -198,4 +198,8 @@ public List<Formatter> getFormatters() {
public List<Object> getFilters() {
return filters;
}

public boolean isMonochrome() {
return monochrome;
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/cucumber/runtime/ScenarioImpl.java
Expand Up @@ -14,7 +14,7 @@
import static java.util.Arrays.asList;

public class ScenarioImpl implements Scenario {
private static final List<String> SEVERITY = asList("passed", "undefined", "pending", "skipped", "failed");
private static final List<String> SEVERITY = asList("passed", "skipped", "undefined", "pending", "failed");
private final List<Result> stepResults = new ArrayList<Result>();
private final Reporter reporter;
private final Set<Tag> tags;
Expand Down
131 changes: 131 additions & 0 deletions core/src/main/java/cucumber/runtime/SummaryCounter.java
@@ -0,0 +1,131 @@
package cucumber.runtime;

import gherkin.formatter.AnsiFormats;
import gherkin.formatter.Format;
import gherkin.formatter.Formats;
import gherkin.formatter.MonochromeFormats;
import gherkin.formatter.model.Result;

import java.io.PrintStream;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

public class SummaryCounter {
public static final long ONE_SECOND = 1000000000;
public static final long ONE_MINUTE = 60 * ONE_SECOND;
public static final String PENDING = "pending";
private SubCounts scenarioSubCounts = new SubCounts();
private SubCounts stepSubCounts = new SubCounts();
private long totalDuration = 0;
private Formats formats;
private Locale locale;

public SummaryCounter(boolean monochrome) {
this(monochrome, Locale.getDefault());
}

public SummaryCounter(boolean monochrome, Locale locale) {
this.locale = locale;
if (monochrome) {
formats = new MonochromeFormats();
} else {
formats = new AnsiFormats();
}
}

public void printSummary(PrintStream out) {
if (stepSubCounts.getTotal() == 0) {
out.println("0 Scenarios");
out.println("0 Steps");
} else {
printScenarioCounts(out);
printStepCounts(out);
}
printDuration(out);
}

private void printStepCounts(PrintStream out) {
out.print(stepSubCounts.getTotal());
out.print(" Steps (");
printSubCounts(out, stepSubCounts);
out.println(")");
}

private void printScenarioCounts(PrintStream out) {
out.print(scenarioSubCounts.getTotal());
out.print(" Scenarios (");
printSubCounts(out, scenarioSubCounts);
out.println(")");
}

private void printSubCounts(PrintStream out, SubCounts subCounts) {
boolean addComma = false;
addComma = printSubCount(out, subCounts.failed, Result.FAILED, addComma);
addComma = printSubCount(out, subCounts.skipped, Result.SKIPPED.getStatus(), addComma);
addComma = printSubCount(out, subCounts.pending, PENDING, addComma);
addComma = printSubCount(out, subCounts.undefined, Result.UNDEFINED.getStatus(), addComma);
addComma = printSubCount(out, subCounts.passed, Result.PASSED, addComma);
}

private boolean printSubCount(PrintStream out, int count, String type, boolean addComma) {
if (count != 0) {
if (addComma) {
out.print(", ");
}
Format format = formats.get(type);
out.print(format.text(count + " " + type));
addComma = true;
}
return addComma;
}

private void printDuration(PrintStream out) {
out.print(String.format("%dm", (totalDuration/ONE_MINUTE)));
DecimalFormat format = new DecimalFormat("0.000", new DecimalFormatSymbols(locale));
out.println(format.format(((double)(totalDuration%ONE_MINUTE))/ONE_SECOND) + "s");
}

public void addStep(Result result) {
addResultToSubCount(stepSubCounts, result.getStatus());
addTime(result.getDuration());
}

public void addScenario(String resultStatus) {
addResultToSubCount(scenarioSubCounts, resultStatus);
}

public void addHookTime(Long duration) {
addTime(duration);
}

private void addTime(Long duration) {
totalDuration += duration != null ? duration : 0;
}

private void addResultToSubCount(SubCounts subCounts, String resultStatus) {
if (resultStatus.equals(Result.FAILED)) {
subCounts.failed++;
} else if (resultStatus.equals(PENDING)) {
subCounts.pending++;
} else if (resultStatus.equals(Result.UNDEFINED.getStatus())) {
subCounts.undefined++;
} else if (resultStatus.equals(Result.SKIPPED.getStatus())) {
subCounts.skipped++;
} else if (resultStatus.equals(Result.PASSED)) {
subCounts.passed++;
}
}
}

class SubCounts {
public int passed = 0;
public int failed = 0;
public int skipped = 0;
public int pending = 0;
public int undefined = 0;

public int getTotal() {
return passed + failed + skipped + pending + undefined;
}
}
Expand Up @@ -11,11 +11,17 @@ public SummaryPrinter(PrintStream out) {
}

public void print(cucumber.runtime.Runtime runtime) {
out.println();
printSummary(runtime);
out.println();
printErrors(runtime);
printSnippets(runtime);
}

private void printSummary(cucumber.runtime.Runtime runtime) {
runtime.printSummary(out);
}

private void printErrors(cucumber.runtime.Runtime runtime) {
for (Throwable error : runtime.getErrors()) {
error.printStackTrace(out);
Expand Down

0 comments on commit f63f6c3

Please sign in to comment.