Skip to content

Commit

Permalink
Option to print output into report, when tests have passed
Browse files Browse the repository at this point in the history
This is PR for #583

A new CLI option: -ginkgo.reportPassed  :
It will print output for each passed test in the generated report,
including JUnit, Teamcity, and Default reporters.

For example, in JUnit (XML), the test output will be added under:
`<testcase> <passed>`

The default behavior (without this option), prints test output
only if the test case (spec) has failed.
  • Loading branch information
manosnoam committed Jun 27, 2019
1 parent 4cb7441 commit 07137e3
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 11 deletions.
6 changes: 6 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type DefaultReporterConfigType struct {
Succinct bool
Verbose bool
FullTrace bool
ReportPassed bool
}

var DefaultReporterConfig = DefaultReporterConfigType{}
Expand Down Expand Up @@ -98,6 +99,7 @@ func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) {
flagSet.BoolVar(&(DefaultReporterConfig.Verbose), prefix+"v", false, "If set, default reporter print out all specs as they begin.")
flagSet.BoolVar(&(DefaultReporterConfig.Succinct), prefix+"succinct", false, "If set, default reporter prints out a very succinct report")
flagSet.BoolVar(&(DefaultReporterConfig.FullTrace), prefix+"trace", false, "If set, default reporter prints out the full stack trace when a failure occurs")
flagSet.BoolVar(&(DefaultReporterConfig.ReportPassed), prefix+"reportPassed", false, "If set, default reporter prints out captured output of passed tests.")
}

func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultReporterConfigType) []string {
Expand Down Expand Up @@ -196,5 +198,9 @@ func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultRepor
result = append(result, fmt.Sprintf("--%strace", prefix))
}

if reporter.ReportPassed {
result = append(result, fmt.Sprintf("--%sreportPassed", prefix))
}

return result
}
2 changes: 1 addition & 1 deletion internal/specrunner/spec_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ func (runner *SpecRunner) reportSpecWillRun(summary *types.SpecSummary) {
}

func (runner *SpecRunner) reportSpecDidComplete(summary *types.SpecSummary, failed bool) {
if failed && len(summary.CapturedOutput) == 0 {
if len(summary.CapturedOutput) == 0 {
summary.CapturedOutput = string(runner.writer.Bytes())
}
for i := len(runner.reporters) - 1; i >= 1; i-- {
Expand Down
9 changes: 6 additions & 3 deletions reporters/default_reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (
)

type DefaultReporter struct {
config config.DefaultReporterConfigType
stenographer stenographer.Stenographer
specSummaries []*types.SpecSummary
config config.DefaultReporterConfigType
stenographer stenographer.Stenographer
specSummaries []*types.SpecSummary
}

func NewDefaultReporter(config config.DefaultReporterConfigType, stenographer stenographer.Stenographer) *DefaultReporter {
Expand Down Expand Up @@ -62,6 +62,9 @@ func (reporter *DefaultReporter) SpecDidComplete(specSummary *types.SpecSummary)
reporter.stenographer.AnnounceSuccesfulSlowSpec(specSummary, reporter.config.Succinct)
} else {
reporter.stenographer.AnnounceSuccesfulSpec(specSummary)
if reporter.config.ReportPassed {
reporter.stenographer.AnnounceCapturedOutput(specSummary.CapturedOutput)
}
}
case types.SpecStatePending:
reporter.stenographer.AnnouncePendingSpec(specSummary, reporter.config.NoisyPendings && !reporter.config.Succinct)
Expand Down
28 changes: 24 additions & 4 deletions reporters/default_reporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,20 @@ var _ = Describe("DefaultReporter", func() {
})
})

Context("Otherwise", func() {
It("should announce the succesful spec", func() {
Context("When the spec is successful", func() {
It("should announce the successful spec", func() {
Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulSpec", spec)))
})

Context("When ReportPassed flag is set", func() {
BeforeEach(func() {
reporterConfig.ReportPassed = true
})

It("should announce the captured output", func() {
Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceCapturedOutput", spec)))
})
})
})
})

Expand Down Expand Up @@ -361,10 +371,20 @@ var _ = Describe("DefaultReporter", func() {
})
})

Context("Otherwise", func() {
It("should announce the succesful spec", func() {
Context("When the spec is successful", func() {
It("should announce the successful spec", func() {
Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuccesfulSpec", spec)))
})

Context("When ReportPassed flag is set", func() {
BeforeEach(func() {
reporterConfig.ReportPassed = true
})

It("should announce the captured output", func() {
Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceCapturedOutput", spec)))
})
})
})
})

Expand Down
14 changes: 13 additions & 1 deletion reporters/junit_reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ type JUnitTestSuite struct {
type JUnitTestCase struct {
Name string `xml:"name,attr"`
ClassName string `xml:"classname,attr"`
PassedMessage *JUnitPassedMessage `xml:"passed,omitempty"`
FailureMessage *JUnitFailureMessage `xml:"failure,omitempty"`
Skipped *JUnitSkipped `xml:"skipped,omitempty"`
Time float64 `xml:"time,attr"`
SystemOut string `xml:"system-out,omitempty"`
}

type JUnitPassedMessage struct {
Message string `xml:",chardata"`
}

type JUnitFailureMessage struct {
Type string `xml:"type,attr"`
Message string `xml:",chardata"`
Expand All @@ -51,6 +56,7 @@ type JUnitReporter struct {
suite JUnitTestSuite
filename string
testSuiteName string
config config.DefaultReporterConfigType
}

//NewJUnitReporter creates a new JUnit XML reporter. The XML will be stored in the passed in filename.
Expand All @@ -60,12 +66,13 @@ func NewJUnitReporter(filename string) *JUnitReporter {
}
}

func (reporter *JUnitReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
func (reporter *JUnitReporter) SpecSuiteWillBegin(ginkgoConfig config.GinkgoConfigType, summary *types.SuiteSummary) {
reporter.suite = JUnitTestSuite{
Name: summary.SuiteDescription,
TestCases: []JUnitTestCase{},
}
reporter.testSuiteName = summary.SuiteDescription
reporter.config = config.DefaultReporterConfig
}

func (reporter *JUnitReporter) SpecWillRun(specSummary *types.SpecSummary) {
Expand Down Expand Up @@ -105,6 +112,11 @@ func (reporter *JUnitReporter) SpecDidComplete(specSummary *types.SpecSummary) {
Name: strings.Join(specSummary.ComponentTexts[1:], " "),
ClassName: reporter.testSuiteName,
}
if reporter.config.ReportPassed && specSummary.State == types.SpecStatePassed {
testCase.PassedMessage = &JUnitPassedMessage{
Message: specSummary.CapturedOutput,
}
}
if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked {
testCase.FailureMessage = &JUnitFailureMessage{
Type: reporter.failureTypeForState(specSummary.State),
Expand Down
11 changes: 9 additions & 2 deletions reporters/junit_reporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import (

var _ = Describe("JUnit Reporter", func() {
var (
outputFile string
reporter Reporter
outputFile string
reporter reporters.JUnitReporter
reporterConfig config.DefaultReporterConfigType
)
testSuiteTime := 12456999 * time.Microsecond
reportedSuiteTime := 12.456
Expand All @@ -39,6 +40,10 @@ var _ = Describe("JUnit Reporter", func() {

reporter = reporters.NewJUnitReporter(outputFile)

reporterConfig = reporter.config {
ReportPassed: true,
}

reporter.SpecSuiteWillBegin(config.GinkgoConfigType{}, &types.SuiteSummary{
SuiteDescription: "My test suite",
NumberOfSpecsThatWillBeRun: 1,
Expand All @@ -63,6 +68,7 @@ var _ = Describe("JUnit Reporter", func() {

spec := &types.SpecSummary{
ComponentTexts: []string{"[Top Level]", "A", "B", "C"},
CapturedOutput: "Spec output: My test case",
State: types.SpecStatePassed,
RunTime: 5 * time.Second,
}
Expand All @@ -89,6 +95,7 @@ var _ = Describe("JUnit Reporter", func() {
Ω(output.TestCases[0].FailureMessage).Should(BeNil())
Ω(output.TestCases[0].Skipped).Should(BeNil())
Ω(output.TestCases[0].Time).Should(Equal(5.0))
Ω(output.TestCases[0].PassedMessage.Message).Should(ContainSubstring("My test case"))
})
})

Expand Down
5 changes: 5 additions & 0 deletions reporters/teamcity_reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
type TeamCityReporter struct {
writer io.Writer
testSuiteName string
config config.DefaultReporterConfigType
}

func NewTeamCityReporter(writer io.Writer) *TeamCityReporter {
Expand Down Expand Up @@ -65,6 +66,10 @@ func (reporter *TeamCityReporter) SpecWillRun(specSummary *types.SpecSummary) {
func (reporter *TeamCityReporter) SpecDidComplete(specSummary *types.SpecSummary) {
testName := escape(strings.Join(specSummary.ComponentTexts[1:], " "))

if reporter.config.ReportPassed && specSummary.State == types.SpecStatePassed {
details := escape(specSummary.CapturedOutput)
fmt.Fprintf(reporter.writer, "%s[testPassed name='%s' details='%s']", messageId, testName, details)
}
if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked {
message := escape(specSummary.Failure.ComponentCodeLocation.String())
details := escape(specSummary.Failure.Message)
Expand Down

0 comments on commit 07137e3

Please sign in to comment.