...

Source file src/github.com/joshdk/go-junit/types.go

Documentation: github.com/joshdk/go-junit

     1  // Copyright Josh Komoroske. All rights reserved.
     2  // Use of this source code is governed by the MIT license,
     3  // a copy of which can be found in the LICENSE.txt file.
     4  
     5  package junit
     6  
     7  import (
     8  	"strings"
     9  	"time"
    10  )
    11  
    12  // Status represents the result of a single a JUnit testcase. Indicates if a
    13  // testcase was run, and if it was successful.
    14  type Status string
    15  
    16  const (
    17  	// StatusPassed represents a JUnit testcase that was run, and did not
    18  	// result in an error or a failure.
    19  	StatusPassed Status = "passed"
    20  
    21  	// StatusSkipped represents a JUnit testcase that was intentionally
    22  	// skipped.
    23  	StatusSkipped Status = "skipped"
    24  
    25  	// StatusFailed represents a JUnit testcase that was run, but resulted in
    26  	// a failure. Failures are violations of declared test expectations,
    27  	// such as a failed assertion.
    28  	StatusFailed Status = "failed"
    29  
    30  	// StatusError represents a JUnit testcase that was run, but resulted in
    31  	// an error. Errors are unexpected violations of the test itself, such as
    32  	// an uncaught exception.
    33  	StatusError Status = "error"
    34  )
    35  
    36  // Totals contains aggregated results across a set of test runs. Is usually
    37  // calculated as a sum of all given test runs, and overrides whatever was given
    38  // at the suite level.
    39  //
    40  // The following relation should hold true.
    41  //   Tests == (Passed + Skipped + Failed + Error)
    42  type Totals struct {
    43  	// Tests is the total number of tests run.
    44  	Tests int `json:"tests" yaml:"tests"`
    45  
    46  	// Passed is the total number of tests that passed successfully.
    47  	Passed int `json:"passed" yaml:"passed"`
    48  
    49  	// Skipped is the total number of tests that were skipped.
    50  	Skipped int `json:"skipped" yaml:"skipped"`
    51  
    52  	// Failed is the total number of tests that resulted in a failure.
    53  	Failed int `json:"failed" yaml:"failed"`
    54  
    55  	// Error is the total number of tests that resulted in an error.
    56  	Error int `json:"error" yaml:"error"`
    57  
    58  	// Duration is the total time taken to run all tests.
    59  	Duration time.Duration `json:"duration" yaml:"duration"`
    60  }
    61  
    62  // Suite represents a logical grouping (suite) of tests.
    63  type Suite struct {
    64  	// Name is a descriptor given to the suite.
    65  	Name string `json:"name" yaml:"name"`
    66  
    67  	// Package is an additional descriptor for the hierarchy of the suite.
    68  	Package string `json:"package" yaml:"package"`
    69  
    70  	// Properties is a mapping of key-value pairs that were available when the
    71  	// tests were run.
    72  	Properties map[string]string `json:"properties,omitempty" yaml:"properties,omitempty"`
    73  
    74  	// Tests is an ordered collection of tests with associated results.
    75  	Tests []Test `json:"tests,omitempty" yaml:"tests,omitempty"`
    76  
    77  	// Suites is an ordered collection of suites with associated tests.
    78  	Suites []Suite `json:"suites,omitempty" yaml:"suites,omitempty"`
    79  
    80  	// SystemOut is textual test output for the suite. Usually output that is
    81  	// written to stdout.
    82  	SystemOut string `json:"stdout,omitempty" yaml:"stdout,omitempty"`
    83  
    84  	// SystemErr is textual test error output for the suite. Usually output that is
    85  	// written to stderr.
    86  	SystemErr string `json:"stderr,omitempty" yaml:"stderr,omitempty"`
    87  
    88  	// Totals is the aggregated results of all tests.
    89  	Totals Totals `json:"totals" yaml:"totals"`
    90  }
    91  
    92  // Aggregate calculates result sums across all tests and nested suites.
    93  func (s *Suite) Aggregate() {
    94  	totals := Totals{Tests: len(s.Tests)}
    95  
    96  	for _, test := range s.Tests {
    97  		totals.Duration += test.Duration
    98  		switch test.Status {
    99  		case StatusPassed:
   100  			totals.Passed++
   101  		case StatusSkipped:
   102  			totals.Skipped++
   103  		case StatusFailed:
   104  			totals.Failed++
   105  		case StatusError:
   106  			totals.Error++
   107  		}
   108  	}
   109  
   110  	// just summing totals from nested suites
   111  	for _, suite := range s.Suites {
   112  		suite.Aggregate()
   113  		totals.Tests += suite.Totals.Tests
   114  		totals.Duration += suite.Totals.Duration
   115  		totals.Passed += suite.Totals.Passed
   116  		totals.Skipped += suite.Totals.Skipped
   117  		totals.Failed += suite.Totals.Failed
   118  		totals.Error += suite.Totals.Error
   119  	}
   120  
   121  	s.Totals = totals
   122  }
   123  
   124  // Test represents the results of a single test run.
   125  type Test struct {
   126  	// Name is a descriptor given to the test.
   127  	Name string `json:"name" yaml:"name"`
   128  
   129  	// Classname is an additional descriptor for the hierarchy of the test.
   130  	Classname string `json:"classname" yaml:"classname"`
   131  
   132  	// Duration is the total time taken to run the tests.
   133  	Duration time.Duration `json:"duration" yaml:"duration"`
   134  
   135  	// Status is the result of the test. Status values are passed, skipped,
   136  	// failure, & error.
   137  	Status Status `json:"status" yaml:"status"`
   138  
   139  	// Message is an textual description optionally included with a skipped,
   140  	// failure, or error test case.
   141  	Message string `json:"message" yaml:"message"`
   142  
   143  	// Error is a record of the failure or error of a test, if applicable.
   144  	//
   145  	// The following relations should hold true.
   146  	//   Error == nil && (Status == Passed || Status == Skipped)
   147  	//   Error != nil && (Status == Failed || Status == Error)
   148  	Error error `json:"error" yaml:"error"`
   149  
   150  	// Additional properties from XML node attributes.
   151  	// Some tools use them to store additional information about test location.
   152  	Properties map[string]string `json:"properties" yaml:"properties"`
   153  
   154  	// SystemOut is textual output for the test case. Usually output that is
   155  	// written to stdout.
   156  	SystemOut string `json:"stdout,omitempty" yaml:"stdout,omitempty"`
   157  
   158  	// SystemErr is textual error output for the test case. Usually output that is
   159  	// written to stderr.
   160  	SystemErr string `json:"stderr,omitempty" yaml:"stderr,omitempty"`
   161  }
   162  
   163  // Error represents an erroneous test result.
   164  type Error struct {
   165  	// Message is a descriptor given to the error. Purpose and values differ by
   166  	// environment.
   167  	Message string `json:"message,omitempty" yaml:"message,omitempty"`
   168  
   169  	// Type is a descriptor given to the error. Purpose and values differ by
   170  	// framework. Value is typically an exception class, such as an assertion.
   171  	Type string `json:"type,omitempty" yaml:"type,omitempty"`
   172  
   173  	// Body is extended text for the error. Purpose and values differ by
   174  	// framework. Value is typically a stacktrace.
   175  	Body string `json:"body,omitempty" yaml:"body,omitempty"`
   176  }
   177  
   178  // Error returns a textual description of the test error.
   179  func (err Error) Error() string {
   180  	switch {
   181  	case strings.TrimSpace(err.Body) != "":
   182  		return err.Body
   183  
   184  	case strings.TrimSpace(err.Message) != "":
   185  		return err.Message
   186  
   187  	default:
   188  		return err.Type
   189  	}
   190  }
   191  

View as plain text