Skip to content

Commit f63f6c3

Browse files
committed
Merge pull request #536 from brasmusson/summary-printout
Merge pull request #536 Print summary at the end of the run. This fixes #195. Update the History.md.
2 parents 4439178 + 40a223a commit f63f6c3

File tree

10 files changed

+572
-10
lines changed

10 files changed

+572
-10
lines changed

History.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* [Core] JUnitFormatter: Fix indentation, hook handling and support all-steps-first execution ([#556](https://github.com/cucumber/cucumber-jvm/pull/556) Björn Rasmusson)
2020
* [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)
2121
* [Core] Test case for the PrettyFormatter. ([#544](https://github.com/cucumber/cucumber-jvm/pull/544) Björn Rasmusson)
22+
* [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)
2223

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

core/src/main/java/cucumber/runtime/Runtime.java

+26-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import gherkin.formatter.model.*;
1414

1515
import java.io.IOException;
16+
import java.io.PrintStream;
1617
import java.util.*;
1718

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

35+
private final SummaryCounter summaryCounter;
3436
final UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker();
3537

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

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

9194
formatter.done();
92-
printSummary();
9395
formatter.close();
96+
printSummary();
9497
}
9598

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

117120
public void disposeBackendWorlds() {
121+
summaryCounter.addScenario(scenarioResult.getStatus());
118122
for (Backend backend : backends) {
119123
backend.disposeWorld();
120124
}
@@ -197,7 +201,7 @@ private void runHookIfTagsMatch(HookDefinition hook, Reporter reporter, Set<Tag>
197201
} finally {
198202
long duration = System.nanoTime() - start;
199203
Result result = new Result(status, duration, error, DUMMY_ARG);
200-
scenarioResult.add(result);
204+
addHookToCounterAndResult(result);
201205
if (isBefore) {
202206
reporter.before(match, result);
203207
} else {
@@ -234,7 +238,9 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
234238
match = glue.stepDefinitionMatch(uri, step, i18n);
235239
} catch (AmbiguousStepDefinitionsException e) {
236240
reporter.match(e.getMatches().get(0));
237-
reporter.result(new Result(Result.FAILED, 0L, e, DUMMY_ARG));
241+
Result result = new Result(Result.FAILED, 0L, e, DUMMY_ARG);
242+
reporter.result(result);
243+
addStepToCounterAndResult(result);
238244
addError(e);
239245
skipNextStep = true;
240246
return;
@@ -245,6 +251,7 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
245251
} else {
246252
reporter.match(Match.UNDEFINED);
247253
reporter.result(Result.UNDEFINED);
254+
addStepToCounterAndResult(Result.UNDEFINED);
248255
skipNextStep = true;
249256
return;
250257
}
@@ -254,7 +261,7 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
254261
}
255262

256263
if (skipNextStep) {
257-
scenarioResult.add(Result.SKIPPED);
264+
addStepToCounterAndResult(Result.SKIPPED);
258265
reporter.result(Result.SKIPPED);
259266
} else {
260267
String status = Result.PASSED;
@@ -270,7 +277,7 @@ public void runStep(String uri, Step step, Reporter reporter, I18n i18n) {
270277
} finally {
271278
long duration = System.nanoTime() - start;
272279
Result result = new Result(status, duration, error, DUMMY_ARG);
273-
scenarioResult.add(result);
280+
addStepToCounterAndResult(result);
274281
reporter.result(result);
275282
}
276283
}
@@ -286,4 +293,18 @@ public static boolean isPending(Throwable t) {
286293
public void writeStepdefsJson() throws IOException {
287294
glue.writeStepdefsJson(runtimeOptions.getFeaturePaths(), runtimeOptions.getDotCucumber());
288295
}
296+
297+
public void printSummary(PrintStream out) {
298+
summaryCounter.printSummary(out);
299+
}
300+
301+
private void addStepToCounterAndResult(Result result) {
302+
scenarioResult.add(result);
303+
summaryCounter.addStep(result);
304+
}
305+
306+
private void addHookToCounterAndResult(Result result) {
307+
scenarioResult.add(result);
308+
summaryCounter.addHookTime(result.getDuration());
309+
}
289310
}

core/src/main/java/cucumber/runtime/RuntimeOptions.java

+4
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,8 @@ public List<Formatter> getFormatters() {
198198
public List<Object> getFilters() {
199199
return filters;
200200
}
201+
202+
public boolean isMonochrome() {
203+
return monochrome;
204+
}
201205
}

core/src/main/java/cucumber/runtime/ScenarioImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import static java.util.Arrays.asList;
1515

1616
public class ScenarioImpl implements Scenario {
17-
private static final List<String> SEVERITY = asList("passed", "undefined", "pending", "skipped", "failed");
17+
private static final List<String> SEVERITY = asList("passed", "skipped", "undefined", "pending", "failed");
1818
private final List<Result> stepResults = new ArrayList<Result>();
1919
private final Reporter reporter;
2020
private final Set<Tag> tags;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package cucumber.runtime;
2+
3+
import gherkin.formatter.AnsiFormats;
4+
import gherkin.formatter.Format;
5+
import gherkin.formatter.Formats;
6+
import gherkin.formatter.MonochromeFormats;
7+
import gherkin.formatter.model.Result;
8+
9+
import java.io.PrintStream;
10+
import java.text.DecimalFormat;
11+
import java.text.DecimalFormatSymbols;
12+
import java.util.Locale;
13+
14+
public class SummaryCounter {
15+
public static final long ONE_SECOND = 1000000000;
16+
public static final long ONE_MINUTE = 60 * ONE_SECOND;
17+
public static final String PENDING = "pending";
18+
private SubCounts scenarioSubCounts = new SubCounts();
19+
private SubCounts stepSubCounts = new SubCounts();
20+
private long totalDuration = 0;
21+
private Formats formats;
22+
private Locale locale;
23+
24+
public SummaryCounter(boolean monochrome) {
25+
this(monochrome, Locale.getDefault());
26+
}
27+
28+
public SummaryCounter(boolean monochrome, Locale locale) {
29+
this.locale = locale;
30+
if (monochrome) {
31+
formats = new MonochromeFormats();
32+
} else {
33+
formats = new AnsiFormats();
34+
}
35+
}
36+
37+
public void printSummary(PrintStream out) {
38+
if (stepSubCounts.getTotal() == 0) {
39+
out.println("0 Scenarios");
40+
out.println("0 Steps");
41+
} else {
42+
printScenarioCounts(out);
43+
printStepCounts(out);
44+
}
45+
printDuration(out);
46+
}
47+
48+
private void printStepCounts(PrintStream out) {
49+
out.print(stepSubCounts.getTotal());
50+
out.print(" Steps (");
51+
printSubCounts(out, stepSubCounts);
52+
out.println(")");
53+
}
54+
55+
private void printScenarioCounts(PrintStream out) {
56+
out.print(scenarioSubCounts.getTotal());
57+
out.print(" Scenarios (");
58+
printSubCounts(out, scenarioSubCounts);
59+
out.println(")");
60+
}
61+
62+
private void printSubCounts(PrintStream out, SubCounts subCounts) {
63+
boolean addComma = false;
64+
addComma = printSubCount(out, subCounts.failed, Result.FAILED, addComma);
65+
addComma = printSubCount(out, subCounts.skipped, Result.SKIPPED.getStatus(), addComma);
66+
addComma = printSubCount(out, subCounts.pending, PENDING, addComma);
67+
addComma = printSubCount(out, subCounts.undefined, Result.UNDEFINED.getStatus(), addComma);
68+
addComma = printSubCount(out, subCounts.passed, Result.PASSED, addComma);
69+
}
70+
71+
private boolean printSubCount(PrintStream out, int count, String type, boolean addComma) {
72+
if (count != 0) {
73+
if (addComma) {
74+
out.print(", ");
75+
}
76+
Format format = formats.get(type);
77+
out.print(format.text(count + " " + type));
78+
addComma = true;
79+
}
80+
return addComma;
81+
}
82+
83+
private void printDuration(PrintStream out) {
84+
out.print(String.format("%dm", (totalDuration/ONE_MINUTE)));
85+
DecimalFormat format = new DecimalFormat("0.000", new DecimalFormatSymbols(locale));
86+
out.println(format.format(((double)(totalDuration%ONE_MINUTE))/ONE_SECOND) + "s");
87+
}
88+
89+
public void addStep(Result result) {
90+
addResultToSubCount(stepSubCounts, result.getStatus());
91+
addTime(result.getDuration());
92+
}
93+
94+
public void addScenario(String resultStatus) {
95+
addResultToSubCount(scenarioSubCounts, resultStatus);
96+
}
97+
98+
public void addHookTime(Long duration) {
99+
addTime(duration);
100+
}
101+
102+
private void addTime(Long duration) {
103+
totalDuration += duration != null ? duration : 0;
104+
}
105+
106+
private void addResultToSubCount(SubCounts subCounts, String resultStatus) {
107+
if (resultStatus.equals(Result.FAILED)) {
108+
subCounts.failed++;
109+
} else if (resultStatus.equals(PENDING)) {
110+
subCounts.pending++;
111+
} else if (resultStatus.equals(Result.UNDEFINED.getStatus())) {
112+
subCounts.undefined++;
113+
} else if (resultStatus.equals(Result.SKIPPED.getStatus())) {
114+
subCounts.skipped++;
115+
} else if (resultStatus.equals(Result.PASSED)) {
116+
subCounts.passed++;
117+
}
118+
}
119+
}
120+
121+
class SubCounts {
122+
public int passed = 0;
123+
public int failed = 0;
124+
public int skipped = 0;
125+
public int pending = 0;
126+
public int undefined = 0;
127+
128+
public int getTotal() {
129+
return passed + failed + skipped + pending + undefined;
130+
}
131+
}

core/src/main/java/cucumber/runtime/snippets/SummaryPrinter.java

+6
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ public SummaryPrinter(PrintStream out) {
1111
}
1212

1313
public void print(cucumber.runtime.Runtime runtime) {
14+
out.println();
15+
printSummary(runtime);
1416
out.println();
1517
printErrors(runtime);
1618
printSnippets(runtime);
1719
}
1820

21+
private void printSummary(cucumber.runtime.Runtime runtime) {
22+
runtime.printSummary(out);
23+
}
24+
1925
private void printErrors(cucumber.runtime.Runtime runtime) {
2026
for (Throwable error : runtime.getErrors()) {
2127
error.printStackTrace(out);

0 commit comments

Comments
 (0)