From f010b650124cfd7f70d1dbb8f999947d8923f688 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 21 May 2024 11:16:27 -0600 Subject: [PATCH] Add --slience-skips and --force-newlines --silence-skips makes it easier to declutter test debugging sessions where only a single spec is being run --force-newlines ensures a newline character appears after every spec. this may help some CI systems flush their output. --- docs/index.md | 4 +++ reporters/default_reporter.go | 10 ++++++- reporters/default_reporter_test.go | 42 +++++++++++++++++++++++++----- types/config.go | 6 +++++ 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/docs/index.md b/docs/index.md index a7fce4a87..c2b88dcde 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2697,6 +2697,8 @@ These mechanisms can all be used in concert. They combine with the following ru - Programmatic filters always apply and result in a non-zero exit code. Any additional CLI filters only apply to the subset of specs selected by the programmatic filters. - When multiple CLI filters (`--label-filter`, `--focus-file/--skip-file`, `--focus/--skip`) are provided they are all ANDed together. The spec must satisfy the label filter query **and** any location-based filters **and** any description based filters. +If you have a large test suite and would like to avoid printing out all the `S` skip delimiters you can run with `--silence-skips` to suppress them. + #### Avoiding filtering out all tests Especially for CI it is useful to fail when all tests were filtered out by accident (either via skip or typo in label filter). @@ -3717,6 +3719,8 @@ Here's why: If running on Github actions: `--github-output` will make the output more readable in the Github actions console. +If your CI system will only flush if a newline character is seen you may want to set `--force-newlines` to ensure that the output is flushed correctly. + ### Supporting Custom Suite Configuration There are contexts where you may want to change some aspects of a suite's behavior based on user-provided configuration. There are two widely adopted means of doing this: environment variables and command-line flags. diff --git a/reporters/default_reporter.go b/reporters/default_reporter.go index 980973370..480730486 100644 --- a/reporters/default_reporter.go +++ b/reporters/default_reporter.go @@ -202,6 +202,11 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) { v := r.conf.Verbosity() inParallel := report.RunningInParallel + //should we completely omit this spec? + if report.State.Is(types.SpecStateSkipped) && r.conf.SilenceSkips { + return + } + header := r.specDenoter if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { header = fmt.Sprintf("[%s]", report.LeafNodeType) @@ -278,9 +283,12 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) { } } - // If we have no content to show, jsut emit the header and return + // If we have no content to show, just emit the header and return if !reportHasContent { r.emit(r.f(highlightColor + header + "{{/}}")) + if r.conf.ForceNewlines { + r.emit("\n") + } return } diff --git a/reporters/default_reporter_test.go b/reporters/default_reporter_test.go index b9a46612c..04f37410e 100644 --- a/reporters/default_reporter_test.go +++ b/reporters/default_reporter_test.go @@ -167,7 +167,7 @@ func S(options ...interface{}) types.SpecReport { return report } -type ConfigFlag uint8 +type ConfigFlag uint16 const ( Succinct ConfigFlag = 1 << iota @@ -177,6 +177,8 @@ const ( FullTrace ShowNodeEvents GithubOutput + SilenceSkips + ForceNewlines Parallel //used in the WillRun => DidRun specs to capture behavior when running in parallel ) @@ -208,6 +210,12 @@ func (cf ConfigFlag) String() string { if cf.Has(GithubOutput) { out = append(out, "github-output") } + if cf.Has(SilenceSkips) { + out = append(out, "silence-skips") + } + if cf.Has(ForceNewlines) { + out = append(out, "force-newlines") + } return strings.Join(out, "|") } @@ -231,6 +239,8 @@ func C(flags ...ConfigFlag) types.ReporterConfig { FullTrace: f.Has(FullTrace), ShowNodeEvents: f.Has(ShowNodeEvents), GithubOutput: f.Has(GithubOutput), + SilenceSkips: f.Has(SilenceSkips), + ForceNewlines: f.Has(ForceNewlines), } } @@ -572,7 +582,10 @@ var _ = Describe("DefaultReporter", func() { S(CLS(cl0, cl1), CTS("A", "B"), "C", cl2), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, "{{green}}"+DENOTER+"{{/}}"), - Case(Verbose, + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, + "{{green}}"+DENOTER+"{{/}}", + ""), + Case(Verbose, Verbose|ForceNewlines, DELIMITER, "{{/}}A {{gray}}B {{/}}{{bold}}C{{/}}", "{{gray}}cl2.go:80{{/}}", @@ -694,7 +707,10 @@ var _ = Describe("DefaultReporter", func() { ), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, spr("{{green}}%s{{/}}", DENOTER)), - Case(Verbose, VeryVerbose, + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, + spr("{{green}}%s{{/}}", DENOTER), + ""), + Case(Verbose, VeryVerbose, Verbose|ForceNewlines, VeryVerbose|ForceNewlines, DELIMITER, "{{/}}{{bold}}A{{/}}", "{{gray}}cl0.go:12{{/}}", @@ -722,7 +738,7 @@ var _ = Describe("DefaultReporter", func() { S(types.NodeTypeIt, "A", cl0, RE("my entry", cl1), ), - Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, + Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, DELIMITER, spr("{{green}}%s [1.000 seconds]{{/}}", DENOTER), "{{green}}{{bold}}A{{/}}", @@ -733,7 +749,7 @@ var _ = Describe("DefaultReporter", func() { " {{gray}}<< Report Entries{{/}}", DELIMITER, ""), - Case(Verbose, VeryVerbose, + Case(Verbose, VeryVerbose, Verbose|ForceNewlines, VeryVerbose|ForceNewlines, DELIMITER, "{{/}}{{bold}}A{{/}}", "{{gray}}cl0.go:12{{/}}", @@ -800,6 +816,9 @@ var _ = Describe("DefaultReporter", func() { ), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, Succinct|ShowNodeEvents, Normal|ShowNodeEvents, spr("{{green}}%s{{/}}", DENOTER)), + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, Succinct|ShowNodeEvents|ForceNewlines, Normal|ShowNodeEvents|ForceNewlines, + spr("{{green}}%s{{/}}", DENOTER), + ""), Case(Verbose, VeryVerbose, //nothing to see here since things are emitted while streaming, which we don't simulate DELIMITER, "{{/}}{{bold}}A{{/}}", @@ -873,7 +892,10 @@ var _ = Describe("DefaultReporter", func() { S(types.NodeTypeIt, "A", types.SpecStateSkipped, cl0), Case(Succinct, Normal, Succinct|Parallel, Normal|Parallel, Verbose, Verbose|Parallel, "{{cyan}}S{{/}}"), - Case(VeryVerbose, + Case(Succinct|ForceNewlines, Normal|ForceNewlines, Succinct|Parallel|ForceNewlines, Normal|Parallel|ForceNewlines, Verbose|ForceNewlines, Verbose|Parallel|ForceNewlines, + "{{cyan}}S{{/}}", + ""), + Case(VeryVerbose, VeryVerbose|ForceNewlines, "{{cyan}}S [SKIPPED]{{/}}", "{{cyan}}{{bold}}A{{/}}", "{{gray}}cl0.go:12{{/}}", @@ -886,6 +908,7 @@ var _ = Describe("DefaultReporter", func() { "{{gray}}cl0.go:12{{/}}", DELIMITER, ""), + Case(Succinct|SilenceSkips, Normal|SilenceSkips, Succinct|Parallel|SilenceSkips, Normal|Parallel|SilenceSkips, Verbose|SilenceSkips, Verbose|Parallel|SilenceSkips, VeryVerbose|SilenceSkips, VeryVerbose|Parallel|SilenceSkips, ""), ), Entry("a user-skipped test", S(types.NodeTypeIt, "A", types.SpecStateSkipped, cl0, @@ -931,6 +954,7 @@ var _ = Describe("DefaultReporter", func() { " {{gray}}<< Timeline{{/}}", DELIMITER, ""), + Case(Succinct|SilenceSkips, Normal|SilenceSkips, Succinct|Parallel|SilenceSkips, Normal|Parallel|SilenceSkips, Verbose|SilenceSkips, Verbose|Parallel|SilenceSkips, VeryVerbose|SilenceSkips, VeryVerbose|Parallel|SilenceSkips, ""), ), Entry("a user-skipped test with timeline content", S(types.NodeTypeIt, "A", types.SpecStateSkipped, cl0, @@ -983,12 +1007,16 @@ var _ = Describe("DefaultReporter", func() { DELIMITER, "", ), + Case(Succinct|SilenceSkips, Normal|SilenceSkips, Succinct|Parallel|SilenceSkips, Normal|Parallel|SilenceSkips, Verbose|SilenceSkips, Verbose|Parallel|SilenceSkips, VeryVerbose|SilenceSkips, VeryVerbose|Parallel|SilenceSkips, ""), ), Entry("a pending test", S(types.NodeTypeIt, "C", types.SpecStatePending, cl2, CTS("A", "B"), CLS(cl0, cl1)), Case(Succinct, Succinct|Parallel, "{{yellow}}P{{/}}"), - Case(Normal, Normal|Parallel, Verbose|Parallel, + Case(Succinct|ForceNewlines, Succinct|Parallel|ForceNewlines, + "{{yellow}}P{{/}}", + ""), + Case(Normal, Normal|Parallel, Verbose|Parallel, Normal|ForceNewlines, Normal|Parallel|ForceNewlines, Verbose|Parallel|ForceNewlines, DELIMITER, "{{yellow}}P [PENDING]{{/}}", "{{/}}A {{gray}}B {{yellow}}{{bold}}C{{/}}", diff --git a/types/config.go b/types/config.go index ad92f4271..66463cf5e 100644 --- a/types/config.go +++ b/types/config.go @@ -91,6 +91,8 @@ type ReporterConfig struct { FullTrace bool ShowNodeEvents bool GithubOutput bool + SilenceSkips bool + ForceNewlines bool JSONReport string JUnitReport string @@ -337,6 +339,10 @@ var ReporterConfigFlags = GinkgoFlags{ Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"}, {KeyPath: "R.GithubOutput", Name: "github-output", SectionKey: "output", Usage: "If set, default reporter prints easier to manage output in Github Actions."}, + {KeyPath: "R.SilenceSkips", Name: "silence-skips", SectionKey: "output", + Usage: "If set, default reporter will not print out skipped tests."}, + {KeyPath: "R.ForceNewlines", Name: "force-newlines", SectionKey: "output", + Usage: "If set, default reporter will ensure a newline appears after each test."}, {KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output", Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."},