github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/reporting_dsl.go (about)

     1  package ginkgo
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/onsi/ginkgo/internal"
     8  	"github.com/onsi/ginkgo/internal/global"
     9  	"github.com/onsi/ginkgo/reporters"
    10  	"github.com/onsi/ginkgo/types"
    11  )
    12  
    13  /*
    14  Report represents the report for a Suite.
    15  It is documented here: https://pkg.go.dev/github.com/onsi/ginkgo/types#Report
    16  */
    17  type Report = types.Report
    18  
    19  /*
    20  Report represents the report for a Spec.
    21  It is documented here: https://pkg.go.dev/github.com/onsi/ginkgo/types#SpecReport
    22  */
    23  type SpecReport = types.SpecReport
    24  
    25  /*
    26  CurrentSpecReport returns information about the current running spec.
    27  The returned object is a types.SpecReport which includes helper methods
    28  to make extracting information about the spec easier.
    29  
    30  You can learn more about SpecReport here: https://pkg.go.dev/github.com/onsi/ginkgo/types#SpecReport
    31  You can learn more about CurrentSpecReport() here: https://onsi.github.io/ginkgo/#getting-a-report-for-the-current-spec
    32  */
    33  func CurrentSpecReport() SpecReport {
    34  	return global.Suite.CurrentSpecReport()
    35  }
    36  
    37  /*
    38   ReportEntryVisibility governs the visibility of ReportEntries in Ginkgo's console reporter
    39  
    40  - ReportEntryVisibilityAlways: the default behavior - the ReportEntry is always emitted.
    41  - ReportEntryVisibilityFailureOrVerbose: the ReportEntry is only emitted if the spec fails or if the tests are run with -v (similar to GinkgoWriters behavior).
    42  - ReportEntryVisibilityNever: the ReportEntry is never emitted though it appears in any generated machine-readable reports (e.g. by setting `--json-report`).
    43  
    44  You can learn more about Report Entries here: https://onsi.github.io/ginkgo/#attaching-data-to-reports
    45  */
    46  type ReportEntryVisibility = types.ReportEntryVisibility
    47  
    48  const ReportEntryVisibilityAlways, ReportEntryVisibilityFailureOrVerbose, ReportEntryVisibilityNever = types.ReportEntryVisibilityAlways, types.ReportEntryVisibilityFailureOrVerbose, types.ReportEntryVisibilityNever
    49  
    50  /*
    51  AddReportEntry generates and adds a new ReportEntry to the current spec's SpecReport.
    52  It can take any of the following arguments:
    53     - A single arbitrary object to attach as the Value of the ReportEntry.  This object will be included in any generated reports and will be emitted to the console when the report is emitted.
    54     - A ReportEntryVisibility enum to control the visibility of the ReportEntry
    55     - An Offset or CodeLocation decoration to control the reported location of the ReportEntry
    56  
    57  If the Value object implements `fmt.Stringer`, it's `String()` representation is used when emitting to the console.
    58  
    59  AddReportEntry() must be called within a Subject or Setup node - not in a Container node.
    60  
    61  You can learn more about Report Entries here: https://onsi.github.io/ginkgo/#attaching-data-to-reports
    62  */
    63  func AddReportEntry(name string, args ...interface{}) {
    64  	cl := types.NewCodeLocation(1)
    65  	reportEntry, err := internal.NewReportEntry(name, cl, args...)
    66  	if err != nil {
    67  		Fail(fmt.Sprintf("Failed to generate Report Entry:\n%s", err.Error()), 1)
    68  	}
    69  	err = global.Suite.AddReportEntry(reportEntry)
    70  	if err != nil {
    71  		Fail(fmt.Sprintf("Failed to add Report Entry:\n%s", err.Error()), 1)
    72  	}
    73  }
    74  
    75  /*
    76  ReportBeforeEach nodes are run for each spec, even if the spec is skipped or pending.  ReportBeforeEach nodes take a function that
    77  receives a SpecReport.  They are called before the spec starts.
    78  
    79  You cannot nest any other Ginkgo nodes within a ReportBeforeEach node's closure.
    80  You can learn more about ReportBeforeEach here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
    81  */
    82  func ReportBeforeEach(body func(SpecReport)) bool {
    83  	return pushNode(internal.NewReportBeforeEachNode(body, types.NewCodeLocation(1)))
    84  }
    85  
    86  /*
    87  ReportAfterEach nodes are run for each spec, even if the spec is skipped or pending.  ReportAfterEach nodes take a function that
    88  receives a SpecReport.  They are called after the spec has completed and receive the final report for the spec.
    89  
    90  You cannot nest any other Ginkgo nodes within a ReportAfterEach node's closure.
    91  You can learn more about ReportAfterEach here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
    92  */
    93  func ReportAfterEach(body func(SpecReport)) bool {
    94  	return pushNode(internal.NewReportAfterEachNode(body, types.NewCodeLocation(1)))
    95  }
    96  
    97  /*
    98  ReportAfterSuite nodes are run at the end of the suite.  ReportAfterSuite nodes take a function that receives a suite Report.
    99  
   100  They are called at the end of the suite, after all specs have run and any AfterSuite or SynchronizedAfterSuite nodes, and are passed in the final report for the suite.
   101  ReportAftersuite nodes must be created at the top-level (i.e. not nested in a Context/Describe/When node)
   102  
   103  When running in parallel, Ginkgo ensures that only one of the parallel nodes runs the ReportAfterSuite and that it is passed a report that is aggregated across
   104  all parallel nodes
   105  
   106  In addition to using ReportAfterSuite to programatically generate suite reports, you can also generate JSON, JUnit, and Teamcity formatted reports using the --json-report, --junit-report, and --teamcity-report ginkgo CLI flags.
   107  
   108  You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure.
   109  You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
   110  You can learn more about Ginkgo's reporting infrastructure, including generating reports with the CLI here: https://onsi.github.io/ginkgo/#generating-machine-readable-reports
   111  */
   112  func ReportAfterSuite(text string, body func(Report)) bool {
   113  	return pushNode(internal.NewReportAfterSuiteNode(text, body, types.NewCodeLocation(1)))
   114  }
   115  
   116  func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.ReporterConfig) {
   117  	body := func(report Report) {
   118  		if reporterConfig.JSONReport != "" {
   119  			err := reporters.GenerateJSONReport(report, reporterConfig.JSONReport)
   120  			if err != nil {
   121  				Fail(fmt.Sprintf("Failed to generate JSON report:\n%s", err.Error()))
   122  			}
   123  		}
   124  		if reporterConfig.JUnitReport != "" {
   125  			err := reporters.GenerateJUnitReport(report, reporterConfig.JUnitReport)
   126  			if err != nil {
   127  				Fail(fmt.Sprintf("Failed to generate JUnit report:\n%s", err.Error()))
   128  			}
   129  		}
   130  		if reporterConfig.TeamcityReport != "" {
   131  			err := reporters.GenerateTeamcityReport(report, reporterConfig.TeamcityReport)
   132  			if err != nil {
   133  				Fail(fmt.Sprintf("Failed to generate Teamcity report:\n%s", err.Error()))
   134  			}
   135  		}
   136  	}
   137  
   138  	flags := []string{}
   139  	if reporterConfig.JSONReport != "" {
   140  		flags = append(flags, "--json-report")
   141  	}
   142  	if reporterConfig.JUnitReport != "" {
   143  		flags = append(flags, "--junit-report")
   144  	}
   145  	if reporterConfig.TeamcityReport != "" {
   146  		flags = append(flags, "--teamcity-report")
   147  	}
   148  	pushNode(internal.NewReportAfterSuiteNode(
   149  		fmt.Sprintf("Autogenerated ReportAfterSuite for %s", strings.Join(flags, " ")),
   150  		body,
   151  		types.NewCustomCodeLocation("autogenerated by Ginkgo"),
   152  	))
   153  }