diff --git a/test/converters/converters_test.go b/test/converters/converters_test.go
index f1c4cef0..dddb4a48 100644
--- a/test/converters/converters_test.go
+++ b/test/converters/converters_test.go
@@ -26,6 +26,7 @@ func TestXCresult3Converters(t *testing.T) {
Name: "rtgtrghtrgTests",
Tests: 2,
Failures: 0,
+ Errors: 0,
Time: 0.26063,
TestCases: []testreport.TestCase{
{ // plain test case
@@ -44,6 +45,7 @@ func TestXCresult3Converters(t *testing.T) {
Name: "rtgtrghtrgUITests",
Tests: 15,
Failures: 3,
+ Errors: 0,
Time: 0.759,
TestCases: []testreport.TestCase{
// class rtgtrghtrg3UITests: XCTestCase inside rtgtrghtrgUITests class
diff --git a/test/converters/junitxml/junitxml.go b/test/converters/junitxml/junitxml.go
index 5ccd728f..90f62b96 100644
--- a/test/converters/junitxml/junitxml.go
+++ b/test/converters/junitxml/junitxml.go
@@ -5,7 +5,7 @@ import (
"strings"
"github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test/testreport"
- "github.com/pkg/errors"
+ errorPkg "github.com/pkg/errors"
)
func (c *Converter) Setup(_ bool) {}
@@ -54,13 +54,9 @@ func parseTestReport(result resultReader) (TestReport, error) {
return TestReport{TestSuites: []TestSuite{testSuite}}, nil
}
- return TestReport{}, errors.Wrap(errors.Wrap(testSuiteErr, string(data)), testReportErr.Error())
+ return TestReport{}, errorPkg.Wrap(errorPkg.Wrap(testSuiteErr, string(data)), testReportErr.Error())
}
-// merges Suites->Cases->Error and Suites->Cases->SystemErr field values into Suites->Cases->Failure field
-// with 2 newlines and error category prefix
-// the two newlines applied only if there is a failure message already
-// this is required because our testing service currently handles failure field properly
func convertTestReport(report TestReport) testreport.TestReport {
convertedReport := testreport.TestReport{
XMLName: report.XMLName,
@@ -76,13 +72,17 @@ func convertTestReport(report TestReport) testreport.TestReport {
func convertTestSuite(testSuite TestSuite) testreport.TestSuite {
convertedTestSuite := testreport.TestSuite{
- XMLName: testSuite.XMLName,
- Name: testSuite.Name,
- Time: testSuite.Time,
+ XMLName: testSuite.XMLName,
+ Name: testSuite.Name,
+ Time: testSuite.Time,
+ Assertions: testSuite.Assertions,
+ Timestamp: testSuite.Timestamp,
+ File: testSuite.File,
}
tests := 0
failures := 0
+ errors := 0
skipped := 0
flattenedTestCases := flattenGroupedTestCases(testSuite.TestCases)
@@ -93,6 +93,9 @@ func convertTestSuite(testSuite TestSuite) testreport.TestSuite {
if convertedTestCase.Failure != nil {
failures++
}
+ if convertedTestCase.Error != nil {
+ errors++
+ }
if convertedTestCase.Skipped != nil {
skipped++
}
@@ -101,12 +104,12 @@ func convertTestSuite(testSuite TestSuite) testreport.TestSuite {
for _, childSuite := range testSuite.TestSuites {
convertedChildSuite := convertTestSuite(childSuite)
-
convertedTestSuite.TestSuites = append(convertedTestSuite.TestSuites, convertedChildSuite)
}
convertedTestSuite.Tests = tests
convertedTestSuite.Failures = failures
+ convertedTestSuite.Errors = errors
convertedTestSuite.Skipped = skipped
return convertedTestSuite
@@ -130,22 +133,49 @@ func flattenGroupedTestCases(testCases []TestCase) []TestCase {
}
for _, flakyFailure := range testCase.FlakyFailures {
- flattenedTestCase.Failure = convertToFailure(flakyFailure.Type, flakyFailure.Message, flakyFailure.SystemErr)
+ flattenedTestCase.Failure = &Failure{
+ Type: flakyFailure.Type,
+ Message: flakyFailure.Message,
+ Value: flakyFailure.Value,
+ }
+ flattenedTestCase.SystemErr = flakyFailure.SystemErr
+ flattenedTestCase.SystemOut = flakyFailure.SystemOut
flattenedTestCases = append(flattenedTestCases, flattenedTestCase)
}
+ flattenedTestCase.Failure = nil
for _, flakyError := range testCase.FlakyErrors {
- flattenedTestCase.Failure = convertToFailure(flakyError.Type, flakyError.Message, flakyError.SystemErr)
+ flattenedTestCase.Error = &Error{
+ Type: flakyError.Type,
+ Message: flakyError.Message,
+ Value: flakyError.Value,
+ }
+ flattenedTestCase.SystemErr = flakyError.SystemErr
+ flattenedTestCase.SystemOut = flakyError.SystemOut
flattenedTestCases = append(flattenedTestCases, flattenedTestCase)
}
+ flattenedTestCase.Error = nil
for _, rerunfailure := range testCase.RerunFailures {
- flattenedTestCase.Failure = convertToFailure(rerunfailure.Type, rerunfailure.Message, rerunfailure.SystemErr)
+ flattenedTestCase.Failure = &Failure{
+ Type: rerunfailure.Type,
+ Message: rerunfailure.Message,
+ Value: rerunfailure.Value,
+ }
+ flattenedTestCase.SystemErr = rerunfailure.SystemErr
+ flattenedTestCase.SystemOut = rerunfailure.SystemOut
flattenedTestCases = append(flattenedTestCases, flattenedTestCase)
}
+ flattenedTestCase.Failure = nil
for _, rerunError := range testCase.RerunErrors {
- flattenedTestCase.Failure = convertToFailure(rerunError.Type, rerunError.Message, rerunError.SystemErr)
+ flattenedTestCase.Error = &Error{
+ Type: rerunError.Type,
+ Message: rerunError.Message,
+ Value: rerunError.Value,
+ }
+ flattenedTestCase.SystemErr = rerunError.SystemErr
+ flattenedTestCase.SystemOut = rerunError.SystemOut
flattenedTestCases = append(flattenedTestCases, flattenedTestCase)
}
@@ -153,33 +183,6 @@ func flattenGroupedTestCases(testCases []TestCase) []TestCase {
return flattenedTestCases
}
-func convertToFailure(itemType, failureMessage, systemErr string) *Failure {
- var message string
- if len(strings.TrimSpace(itemType)) > 0 {
- message = itemType
- }
- if len(strings.TrimSpace(failureMessage)) > 0 {
- if len(message) > 0 {
- message += ": "
- }
- message += failureMessage
- }
-
- if len(strings.TrimSpace(systemErr)) > 0 {
- if len(message) > 0 {
- message += "\n\n"
- }
- message += "System error:\n" + systemErr
- }
-
- if len(message) > 0 {
- return &Failure{
- Value: message,
- }
- }
- return nil
-}
-
func convertTestCase(testCase TestCase) testreport.TestCase {
convertedTestCase := testreport.TestCase{
XMLName: testCase.XMLName,
@@ -187,17 +190,17 @@ func convertTestCase(testCase TestCase) testreport.TestCase {
Name: testCase.Name,
ClassName: testCase.ClassName,
Time: testCase.Time,
+ Assertions: testCase.Assertions,
+ File: testCase.File,
+ Line: testCase.Line,
+ Failure: convertFailure(testCase.Failure),
+ Error: convertError(testCase.Error),
+ Skipped: convertSkipped(testCase.Skipped),
Properties: convertProperties(testCase.Properties),
+ SystemOut: convertSystemOut(testCase.SystemOut),
+ SystemErr: convertSystemErr(testCase.SystemErr),
}
- if testCase.Skipped != nil {
- convertedTestCase.Skipped = &testreport.Skipped{
- XMLName: testCase.Skipped.XMLName,
- }
- }
-
- convertedTestCase.Failure = convertErrorsToFailure(testCase.Failure, testCase.Error, testCase.SystemErr)
-
return convertedTestCase
}
@@ -218,38 +221,62 @@ func convertProperties(properties *Properties) *testreport.Properties {
return convertedProperties
}
-func convertErrorsToFailure(failure *Failure, error *Error, systemErr string) *testreport.Failure {
- var messages []string
+func convertSystemOut(systemOut string) *testreport.SystemOut {
+ if len(strings.TrimSpace(systemOut)) == 0 {
+ return nil
+ }
+
+ return &testreport.SystemOut{
+ XMLName: xml.Name{Local: "system-out"},
+ Value: strings.TrimSpace(systemOut),
+ }
+}
+
+func convertSystemErr(systemErr string) *testreport.SystemErr {
+ if len(strings.TrimSpace(systemErr)) == 0 {
+ return nil
+ }
- if failure != nil {
- if len(strings.TrimSpace(failure.Message)) > 0 {
- messages = append(messages, failure.Message)
- }
+ return &testreport.SystemErr{
+ XMLName: xml.Name{Local: "system-err"},
+ Value: strings.TrimSpace(systemErr),
+ }
+}
- if len(strings.TrimSpace(failure.Value)) > 0 {
- messages = append(messages, failure.Value)
- }
+func convertSkipped(skipped *Skipped) *testreport.Skipped {
+ if skipped == nil {
+ return nil
}
- if error != nil {
- if len(strings.TrimSpace(error.Message)) > 0 {
- messages = append(messages, "Error message:\n"+error.Message)
- }
+ return &testreport.Skipped{
+ XMLName: xml.Name{Local: "skipped"},
+ Message: skipped.Message,
+ Value: strings.TrimSpace(skipped.Value),
+ }
+}
- if len(strings.TrimSpace(error.Value)) > 0 {
- messages = append(messages, "Error value:\n"+error.Value)
- }
+func convertFailure(failure *Failure) *testreport.Failure {
+ if failure == nil {
+ return nil
}
- if len(systemErr) > 0 {
- messages = append(messages, "System error:\n"+systemErr)
+ return &testreport.Failure{
+ XMLName: xml.Name{Local: "failure"},
+ Type: failure.Type,
+ Message: failure.Message,
+ Value: strings.TrimSpace(failure.Value),
}
+}
- if len(messages) > 0 {
- return &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: strings.Join(messages, "\n\n"),
- }
+func convertError(error *Error) *testreport.Error {
+ if error == nil {
+ return nil
+ }
+
+ return &testreport.Error{
+ XMLName: xml.Name{Local: "error"},
+ Type: error.Type,
+ Message: error.Message,
+ Value: strings.TrimSpace(error.Value),
}
- return nil
}
diff --git a/test/converters/junitxml/junitxml_test.go b/test/converters/junitxml/junitxml_test.go
index 265b8a10..a63ba356 100644
--- a/test/converters/junitxml/junitxml_test.go
+++ b/test/converters/junitxml/junitxml_test.go
@@ -35,279 +35,341 @@ func Test_convertTestReport(t *testing.T) {
suites []TestSuite
want []testreport.TestSuite
}{
+ // Passing test cases - no failure, error, or skipped
{
- name: "regroup error message",
+ name: "Passing test case - no details",
suites: []TestSuite{{TestCases: []TestCase{
{
- Error: &Error{
- Message: "error message",
- },
+ Name: "passingTest",
+ ClassName: "TestClass",
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 0, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "Error message:\nerror message",
- },
+ Name: "passingTest",
+ ClassName: "TestClass",
},
}}},
},
+
{
- name: "regroup error body",
+ name: "Passing test case - system error and output",
suites: []TestSuite{{TestCases: []TestCase{
{
- Error: &Error{
- Value: "error message",
- },
+ Name: "passingTestWithOutput",
+ ClassName: "TestClass",
+ SystemOut: "Test passed\nExecution time: 100ms",
+ SystemErr: "Info: deprecated method used",
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 0, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "Error value:\nerror message",
- },
+ Name: "passingTestWithOutput",
+ ClassName: "TestClass",
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Test passed\nExecution time: 100ms"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "Info: deprecated method used"},
},
}}},
},
+
+ // Failure test cases
{
- name: "regroup system err",
+ name: "Failure - no details",
suites: []TestSuite{{TestCases: []TestCase{
{
- SystemErr: "error message",
+ Name: "failureNoDetailsTest",
+ Failure: &Failure{},
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 1, Errors: 0, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "System error:\nerror message",
- },
+ Name: "failureNoDetailsTest",
+ Failure: &testreport.Failure{XMLName: xml.Name{Local: "failure"}, Value: ""},
},
}}},
},
{
- name: "regroup error message - multiple test cases",
+ name: "Failure - system error and output only",
suites: []TestSuite{{TestCases: []TestCase{
{
- Error: &Error{
- Message: "error message",
- },
- },
- {
- Error: &Error{
- Message: "error message2",
- },
+ Name: "failureSystemOutputTest",
+ Failure: &Failure{},
+ SystemOut: "Test execution started",
+ SystemErr: "Error: NullPointerException",
},
}}},
- want: []testreport.TestSuite{{Tests: 2, Failures: 2, Skipped: 0, TestCases: []testreport.TestCase{
- {
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "Error message:\nerror message",
- },
- },
+ want: []testreport.TestSuite{{Tests: 1, Failures: 1, Errors: 0, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "Error message:\nerror message2",
- },
+ Name: "failureSystemOutputTest",
+ Failure: &testreport.Failure{XMLName: xml.Name{Local: "failure"}, Value: ""},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Test execution started"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "Error: NullPointerException"},
},
}}},
},
+
{
- name: "regroup error body - multiple test cases",
+ name: "Failure - content only",
suites: []TestSuite{{TestCases: []TestCase{
{
- Error: &Error{
- Value: "error message",
- },
+ Name: "simpleFailureTest",
+ Failure: &Failure{Value: "assertion failed"},
},
+ }}},
+ want: []testreport.TestSuite{{Tests: 1, Failures: 1, Errors: 0, Skipped: 0, TestCases: []testreport.TestCase{
{
- Error: &Error{
- Value: "error message2",
- },
+ Name: "simpleFailureTest",
+ Failure: &testreport.Failure{XMLName: xml.Name{Local: "failure"}, Value: "assertion failed"},
},
}}},
- want: []testreport.TestSuite{{Tests: 2, Failures: 2, Skipped: 0, TestCases: []testreport.TestCase{
+ },
+
+ {
+ name: "Failure - all attributes and system output",
+ suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "Error value:\nerror message",
- },
+ Name: "complexFailureTest",
+ Failure: &Failure{Type: "AssertionError", Message: "expected true", Value: "Stack trace"},
+ SystemOut: "Test output: started",
+ SystemErr: "Warning: deprecated API",
},
+ }}},
+ want: []testreport.TestSuite{{Tests: 1, Failures: 1, Errors: 0, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "Error value:\nerror message2",
- },
+ Name: "complexFailureTest",
+ Failure: &testreport.Failure{XMLName: xml.Name{Local: "failure"}, Type: "AssertionError", Message: "expected true", Value: "Stack trace"},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Test output: started"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "Warning: deprecated API"},
},
}}},
},
+
+ // Error test cases
{
- name: "regroup system err - multiple test cases",
+ name: "Error - no details",
suites: []TestSuite{{TestCases: []TestCase{
{
- SystemErr: "error message",
+ Name: "errorNoDetailsTest",
+ Error: &Error{},
},
+ }}},
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 1, Skipped: 0, TestCases: []testreport.TestCase{
{
- SystemErr: "error message2",
+ Name: "errorNoDetailsTest",
+ Error: &testreport.Error{XMLName: xml.Name{Local: "error"}, Value: ""},
},
}}},
- want: []testreport.TestSuite{{Tests: 2, Failures: 2, Skipped: 0, TestCases: []testreport.TestCase{
+ },
+
+ {
+ name: "Error - system error and output only",
+ suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "System error:\nerror message",
- },
+ Name: "errorSystemOutputTest",
+ Error: &Error{},
+ SystemOut: "Initialization complete",
+ SystemErr: "Critical error occurred",
},
+ }}},
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 1, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "System error:\nerror message2",
- },
+ Name: "errorSystemOutputTest",
+ Error: &testreport.Error{XMLName: xml.Name{Local: "error"}, Value: ""},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Initialization complete"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "Critical error occurred"},
},
}}},
},
+
{
- name: "should not touch failure",
+ name: "Error - content only",
suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &Failure{
- Value: "error message",
- },
+ Name: "simpleErrorTest",
+ Error: &Error{Value: "null pointer"},
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 1, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "error message",
- },
+ Name: "simpleErrorTest",
+ Error: &testreport.Error{XMLName: xml.Name{Local: "error"}, Value: "null pointer"},
},
}}},
},
+
{
- name: "should append error body to failure",
+ name: "Error - all attributes and system output",
suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &Failure{
- Value: "failure message",
- },
- Error: &Error{
- Value: "error value",
- },
+ Name: "complexErrorTest",
+ Error: &Error{Type: "NullPointerException", Message: "object was null", Value: "Full stack trace"},
+ SystemOut: "Test setup complete",
+ SystemErr: "System error: OutOfMemory",
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 1, Skipped: 0, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "failure message\n\nError value:\nerror value",
- },
+ Name: "complexErrorTest",
+ Error: &testreport.Error{XMLName: xml.Name{Local: "error"}, Type: "NullPointerException", Message: "object was null", Value: "Full stack trace"},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Test setup complete"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "System error: OutOfMemory"},
},
}}},
},
+
+ // Skipped test cases
{
- name: "should append error message to failure",
+ name: "Skipped - no details",
suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &Failure{
- Value: "Failure message",
- },
- Error: &Error{
- Message: "error value",
- },
+ Name: "skippedNoDetailsTest",
+ Skipped: &Skipped{},
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 0, Skipped: 1, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "Failure message\n\nError message:\nerror value",
- },
+ Name: "skippedNoDetailsTest",
+ Skipped: &testreport.Skipped{XMLName: xml.Name{Local: "skipped"}, Value: ""},
},
}}},
},
+
{
- name: "should append system error to failure",
+ name: "Skipped - system error and output only",
suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &Failure{
- Value: "failure message",
- },
- SystemErr: "error value",
+ Name: "skippedSystemOutputTest",
+ Skipped: &Skipped{},
+ SystemOut: "Skipping test due to unmet prerequisites",
+ SystemErr: "Warning: missing configuration",
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 0, Skipped: 1, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "failure message\n\nSystem error:\nerror value",
- },
+ Name: "skippedSystemOutputTest",
+ Skipped: &testreport.Skipped{XMLName: xml.Name{Local: "skipped"}, Value: ""},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Skipping test due to unmet prerequisites"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "Warning: missing configuration"},
},
}}},
},
+
{
- name: "should append system error, error message, error body to failure",
+ name: "Skipped - content only",
suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &Failure{
- Value: "failure message",
- },
- SystemErr: "error value",
+ Name: "simpleSkippedTest",
+ Skipped: &Skipped{Value: "Test not implemented"},
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 0, Skipped: 1, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "failure message\n\nSystem error:\nerror value",
- },
+ Name: "simpleSkippedTest",
+ Skipped: &testreport.Skipped{XMLName: xml.Name{Local: "skipped"}, Value: "Test not implemented"},
},
}}},
},
+
{
- name: "should append system error, error message, error body to failure",
+ name: "Skipped - all attributes and system output",
suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &Failure{
- Message: "failure message",
- Value: "failure content",
- },
- SystemErr: "error value",
- Error: &Error{
- Message: "message",
- Value: "value",
- },
+ Name: "complexSkippedTest",
+ Skipped: &Skipped{Message: "Environment not ready", Value: "Resource pool unavailable"},
+ SystemOut: "Setup started but aborted",
+ SystemErr: "Resource pool unavailable",
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 1, Failures: 0, Errors: 0, Skipped: 1, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "failure message\n\nfailure content\n\nError message:\nmessage\n\nError value:\nvalue\n\nSystem error:\nerror value",
- },
+ Name: "complexSkippedTest",
+ Skipped: &testreport.Skipped{XMLName: xml.Name{Local: "skipped"}, Message: "Environment not ready", Value: "Resource pool unavailable"},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Setup started but aborted"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "Resource pool unavailable"},
},
}}},
},
+
+ // Multiple test cases in one suite
{
- name: "Should convert Message attribute of Failure element to the value of a Failure element",
+ name: "Multiple test cases with mixed results",
suites: []TestSuite{{TestCases: []TestCase{
{
- Failure: &Failure{
- Message: "ErrorMsg",
- },
+ Name: "passingTest",
+ ClassName: "TestClass",
+ },
+ {
+ Name: "failureTest",
+ Failure: &Failure{Value: "expected true"},
+ },
+ {
+ Name: "errorTest",
+ Error: &Error{Value: "null pointer"},
+ },
+ {
+ Name: "skippedTest",
+ Skipped: &Skipped{},
+ },
+ {
+ Name: "anotherPassingTest",
+ ClassName: "TestClass",
+ SystemOut: "All good",
+ },
+ {
+ Name: "anotherFailureTest",
+ Failure: &Failure{Type: "AssertionError", Message: "value mismatch", Value: "Stack trace"},
+ SystemErr: "Error details",
+ },
+ {
+ Name: "anotherErrorTest",
+ Error: &Error{Type: "IOException", Message: "file not found", Value: "Stack trace"},
+ SystemOut: "Attempted to read file",
+ SystemErr: "File read error",
+ },
+ {
+ Name: "anotherSkippedTest",
+ Skipped: &Skipped{Message: "Dependency missing"},
+ SystemOut: "Skipping due to missing dependency",
},
}}},
- want: []testreport.TestSuite{{Tests: 1, Failures: 1, Skipped: 0, TestCases: []testreport.TestCase{
+ want: []testreport.TestSuite{{Tests: 8, Failures: 2, Errors: 2, Skipped: 2, TestCases: []testreport.TestCase{
{
- Failure: &testreport.Failure{
- XMLName: xml.Name{Local: "failure"},
- Value: "ErrorMsg",
- },
+ Name: "passingTest",
+ ClassName: "TestClass",
+ },
+ {
+ Name: "failureTest",
+ Failure: &testreport.Failure{XMLName: xml.Name{Local: "failure"}, Value: "expected true"},
+ },
+ {
+ Name: "errorTest",
+ Error: &testreport.Error{XMLName: xml.Name{Local: "error"}, Value: "null pointer"},
+ },
+ {
+ Name: "skippedTest",
+ Skipped: &testreport.Skipped{XMLName: xml.Name{Local: "skipped"}, Value: ""},
+ },
+ {
+ Name: "anotherPassingTest",
+ ClassName: "TestClass",
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "All good"},
+ },
+ {
+ Name: "anotherFailureTest",
+ Failure: &testreport.Failure{XMLName: xml.Name{Local: "failure"}, Type: "AssertionError", Message: "value mismatch", Value: "Stack trace"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "Error details"},
+ },
+ {
+ Name: "anotherErrorTest",
+ Error: &testreport.Error{XMLName: xml.Name{Local: "error"}, Type: "IOException", Message: "file not found", Value: "Stack trace"},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Attempted to read file"},
+ SystemErr: &testreport.SystemErr{XMLName: xml.Name{Local: "system-err"}, Value: "File read error"},
+ },
+ {
+ Name: "anotherSkippedTest",
+ Skipped: &testreport.Skipped{XMLName: xml.Name{Local: "skipped"}, Message: "Dependency missing"},
+ SystemOut: &testreport.SystemOut{XMLName: xml.Name{Local: "system-out"}, Value: "Skipping due to missing dependency"},
},
}}},
},
@@ -365,7 +427,7 @@ func TestConverter_Convert(t *testing.T) {
Time: 0.17543494701385498,
Failure: &testreport.Failure{
XMLName: xml.Name{Local: "failure"},
- Value: "XCTAssertTrue failed",
+ Message: "XCTAssertTrue failed",
},
},
},
@@ -457,6 +519,7 @@ Testmo test management software - https://www.testmo.com/
Name: "Tests.Registration",
Tests: 3,
Failures: 0,
+ Errors: 0,
Time: 6.605871,
TestCases: []testreport.TestCase{
{
@@ -507,7 +570,8 @@ Testmo test management software - https://www.testmo.com/
XMLName: xml.Name{
Local: "failure",
},
- Value: "Assertion error message",
+ Type: "AssertionError",
+ Message: "Assertion error message",
},
},
},
@@ -574,32 +638,175 @@ func TestConverter_Convert_Grouped_report(t *testing.T) {
XMLName: xml.Name{Space: "", Local: ""},
TestSuites: []testreport.TestSuite{
{
- XMLName: xml.Name{Space: "", Local: "testsuite"},
- Name: "My Test Suite",
- Tests: 7, Failures: 6, Skipped: 1,
- Time: 28.844,
+ XMLName: xml.Name{Space: "", Local: "testsuite"},
+ Name: "My Test Suite",
+ Tests: 8,
+ Failures: 3,
+ Errors: 3,
+ Skipped: 1,
+ Time: 28.844,
TestCases: []testreport.TestCase{
- {XMLName: xml.Name{Space: "", Local: "testcase"}, ConfigurationHash: "", Name: "Testcase number 1", ClassName: "example.exampleTest", Time: 0.764,
- Failure: nil,
- Skipped: &testreport.Skipped{XMLName: xml.Name{Space: "", Local: "skipped"}}},
- {XMLName: xml.Name{Space: "", Local: "testcase"}, ConfigurationHash: "", Name: "Testcase number 2", ClassName: "example.exampleTest", Time: 0.164,
- Failure: &testreport.Failure{XMLName: xml.Name{Space: "", Local: "failure"}, Value: "System error:\nSome error message 2"},
- Skipped: nil},
- {XMLName: xml.Name{Space: "", Local: "testcase"}, ConfigurationHash: "", Name: "Testcase number 3", ClassName: "example.exampleTest", Time: 0.445,
- Failure: &testreport.Failure{XMLName: xml.Name{Space: "", Local: "failure"}, Value: "Failure message\n\nError value:\nError\n\nSystem error:\nSome error message 3"},
- Skipped: nil},
- {XMLName: xml.Name{Space: "", Local: "testcase"}, ConfigurationHash: "", Name: "Testcase number 3", ClassName: "example.exampleTest", Time: 0,
- Failure: &testreport.Failure{XMLName: xml.Name{Space: "", Local: "failure"}, Value: "System error:\nFlaky failure system error"},
- Skipped: nil},
- {XMLName: xml.Name{Space: "", Local: "testcase"}, ConfigurationHash: "", Name: "Testcase number 3", ClassName: "example.exampleTest", Time: 0,
- Failure: &testreport.Failure{XMLName: xml.Name{Space: "", Local: "failure"}, Value: "System error:\nFlaky error system error"},
- Skipped: nil},
- {XMLName: xml.Name{Space: "", Local: "testcase"}, ConfigurationHash: "", Name: "Testcase number 3", ClassName: "example.exampleTest", Time: 0,
- Failure: &testreport.Failure{XMLName: xml.Name{Space: "", Local: "failure"}, Value: "System error:\nRerun failure system error"},
- Skipped: nil},
- {XMLName: xml.Name{Space: "", Local: "testcase"}, ConfigurationHash: "", Name: "Testcase number 3", ClassName: "example.exampleTest", Time: 0,
- Failure: &testreport.Failure{XMLName: xml.Name{Space: "", Local: "failure"}, Value: "System error:\nRerun error system error"},
- Skipped: nil},
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 1",
+ ClassName: "example.exampleTest",
+ Time: 0.764,
+ Failure: nil,
+ Error: nil,
+ Skipped: &testreport.Skipped{
+ XMLName: xml.Name{Space: "", Local: "skipped"},
+ Value: "Skipped",
+ },
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "[INFO] 13:12:43:\n[INFO] 13:12:43:\tLog line 1 1\n[INFO] 13:12:43:\tLog line 2 1",
+ },
+ },
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 2",
+ ClassName: "example.exampleTest",
+ Time: 0.164,
+ Failure: nil,
+ Skipped: nil,
+ Error: nil,
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "[INFO] 13:12:43:\n[INFO] 13:12:43:\tLog line 1 2\n[INFO] 13:12:43:\tLog line 2 2",
+ },
+ SystemErr: &testreport.SystemErr{
+ XMLName: xml.Name{Space: "", Local: "system-err"},
+ Value: "Some error message 2",
+ },
+ },
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 3",
+ ClassName: "example.exampleTest",
+ Time: 0.445,
+ Error: nil,
+ Skipped: nil,
+ Failure: &testreport.Failure{
+ XMLName: xml.Name{Space: "", Local: "failure"},
+ Value: "Failure message",
+ },
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "[INFO] 13:12:43:\n[INFO] 13:12:43:\tLog line 1 3\n[INFO] 13:12:43:\tLog line 2 3",
+ },
+ SystemErr: &testreport.SystemErr{
+ XMLName: xml.Name{Space: "", Local: "system-err"},
+ Value: "Some error message 3",
+ },
+ },
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 3",
+ ClassName: "example.exampleTest",
+ Time: 0,
+ Skipped: nil,
+ Error: nil,
+ Failure: &testreport.Failure{
+ XMLName: xml.Name{Space: "", Local: "failure"},
+ Value: "",
+ },
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "Flaky failure system out",
+ },
+ SystemErr: &testreport.SystemErr{
+ XMLName: xml.Name{Space: "", Local: "system-err"},
+ Value: "Flaky failure system error",
+ },
+ },
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 3",
+ ClassName: "example.exampleTest",
+ Time: 0,
+ Skipped: nil,
+ Error: nil,
+ Failure: &testreport.Failure{
+ XMLName: xml.Name{Space: "", Local: "failure"},
+ Value: "",
+ },
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "Rerun failure system out",
+ },
+ SystemErr: &testreport.SystemErr{
+ XMLName: xml.Name{Space: "", Local: "system-err"},
+ Value: "Rerun failure system error",
+ },
+ },
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 4",
+ ClassName: "example.exampleTest",
+ Time: 0.352,
+ Skipped: nil,
+ Failure: nil,
+ Error: &testreport.Error{
+ XMLName: xml.Name{Space: "", Local: "error"},
+ Value: "Error message",
+ },
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "[INFO] 13:12:43:\n[INFO] 13:12:43:\tLog line 1 4\n[INFO] 13:12:43:\tLog line 2 4",
+ },
+ SystemErr: &testreport.SystemErr{
+ XMLName: xml.Name{Space: "", Local: "system-err"},
+ Value: "Some error message 4",
+ },
+ },
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 4",
+ ClassName: "example.exampleTest",
+ Time: 0,
+ Skipped: nil,
+ Failure: nil,
+ Error: &testreport.Error{
+ XMLName: xml.Name{Space: "", Local: "error"},
+ Value: "",
+ },
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "Flaky error system out",
+ },
+ SystemErr: &testreport.SystemErr{
+ XMLName: xml.Name{Space: "", Local: "system-err"},
+ Value: "Flaky error system error",
+ },
+ },
+ {
+ XMLName: xml.Name{Space: "", Local: "testcase"},
+ ConfigurationHash: "",
+ Name: "Testcase number 4",
+ ClassName: "example.exampleTest",
+ Time: 0,
+ Skipped: nil,
+ Failure: nil,
+ Error: &testreport.Error{
+ XMLName: xml.Name{Space: "", Local: "error"},
+ Value: "",
+ },
+ SystemOut: &testreport.SystemOut{
+ XMLName: xml.Name{Space: "", Local: "system-out"},
+ Value: "Rerun error system out",
+ },
+ SystemErr: &testreport.SystemErr{
+ XMLName: xml.Name{Space: "", Local: "system-err"},
+ Value: "Rerun error system error",
+ },
+ },
},
},
},
diff --git a/test/converters/junitxml/models.go b/test/converters/junitxml/models.go
index b9e4ec9f..a7dbc4eb 100644
--- a/test/converters/junitxml/models.go
+++ b/test/converters/junitxml/models.go
@@ -16,24 +16,30 @@ type TestSuite struct {
Name string `xml:"name,attr"`
Tests int `xml:"tests,attr"`
Failures int `xml:"failures,attr"`
- Skipped int `xml:"skipped,attr"`
Errors int `xml:"errors,attr"`
+ Skipped int `xml:"skipped,attr"`
+ Assertions int `xml:"assertions,attr,omitempty"`
Time float64 `xml:"time,attr"`
- TestCases []TestCase `xml:"testcase"`
- TestSuites []TestSuite `xml:"testsuite"`
+ Timestamp string `xml:"timestamp,attr,omitempty"`
+ File string `xml:"file,attr,omitempty"`
+ TestCases []TestCase `xml:"testcase,omitempty"`
+ TestSuites []TestSuite `xml:"testsuite,omitempty"`
}
// TestCase ...
type TestCase struct {
XMLName xml.Name `xml:"testcase"`
- ConfigurationHash string `xml:"configuration-hash,attr"`
+ ConfigurationHash string `xml:"configuration-hash,attr,omitempty"`
Name string `xml:"name,attr"`
ClassName string `xml:"classname,attr"`
+ Assertions int `xml:"assertions,attr,omitempty"`
Time float64 `xml:"time,attr"`
+ File string `xml:"file,attr,omitempty"`
+ Line int `xml:"line,attr,omitempty"`
Failure *Failure `xml:"failure,omitempty"`
- Properties *Properties `xml:"properties,omitempty"`
- Skipped *Skipped `xml:"skipped,omitempty"`
Error *Error `xml:"error,omitempty"`
+ Skipped *Skipped `xml:"skipped,omitempty"`
+ Properties *Properties `xml:"properties,omitempty"`
SystemErr string `xml:"system-err,omitempty"`
SystemOut string `xml:"system-out,omitempty"`
@@ -45,32 +51,36 @@ type TestCase struct {
type FlakyFailure struct {
XMLName xml.Name `xml:"flakyFailure"`
- Message string `xml:"message,attr"`
- Type string `xml:"type,attr"`
+ Type string `xml:"type,attr,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
+ Value string `xml:",chardata"`
SystemErr string `xml:"system-err,omitempty"`
SystemOut string `xml:"system-out,omitempty"`
}
type FlakyError struct {
XMLName xml.Name `xml:"flakyError"`
- Message string `xml:"message,attr"`
- Type string `xml:"type,attr"`
+ Type string `xml:"type,attr,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
+ Value string `xml:",chardata"`
SystemErr string `xml:"system-err,omitempty"`
SystemOut string `xml:"system-out,omitempty"`
}
type RerunFailure struct {
XMLName xml.Name `xml:"rerunFailure"`
- Message string `xml:"message,attr"`
- Type string `xml:"type,attr"`
+ Type string `xml:"type,attr,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
+ Value string `xml:",chardata"`
SystemErr string `xml:"system-err,omitempty"`
SystemOut string `xml:"system-out,omitempty"`
}
type RerunError struct {
XMLName xml.Name `xml:"rerunError"`
- Message string `xml:"message,attr"`
- Type string `xml:"type,attr"`
+ Type string `xml:"type,attr,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
+ Value string `xml:",chardata"`
SystemErr string `xml:"system-err,omitempty"`
SystemOut string `xml:"system-out,omitempty"`
}
@@ -78,18 +88,22 @@ type RerunError struct {
// Failure ...
type Failure struct {
XMLName xml.Name `xml:"failure,omitempty"`
+ Type string `xml:"type,attr,omitempty"`
Message string `xml:"message,attr,omitempty"`
Value string `xml:",chardata"`
}
-// Skipped ...
-type Skipped struct {
- XMLName xml.Name `xml:"skipped,omitempty"`
-}
-
// Error ...
type Error struct {
XMLName xml.Name `xml:"error,omitempty"`
+ Type string `xml:"type,attr,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
+ Value string `xml:",chardata"`
+}
+
+// Skipped ...
+type Skipped struct {
+ XMLName xml.Name `xml:"skipped,omitempty"`
Message string `xml:"message,attr,omitempty"`
Value string `xml:",chardata"`
}
diff --git a/test/converters/junitxml/testdata/flaky_test.xml b/test/converters/junitxml/testdata/flaky_test.xml
index 5e3a14a5..ecda1d37 100644
--- a/test/converters/junitxml/testdata/flaky_test.xml
+++ b/test/converters/junitxml/testdata/flaky_test.xml
@@ -40,6 +40,14 @@
Flaky failure system out
Flaky failure system error
+
+
+
+
+ Error message
Rerun error stack trace
Rerun error system out
@@ -50,6 +58,6 @@
Flaky error system out
Flaky error system error
- Error
+
\ No newline at end of file
diff --git a/test/testdata/ios_device_config_xml_output.golden b/test/testdata/ios_device_config_xml_output.golden
index 66849f25..3437627c 100644
--- a/test/testdata/ios_device_config_xml_output.golden
+++ b/test/testdata/ios_device_config_xml_output.golden
@@ -1,16 +1,16 @@
-
-
+
+
DarkAndLightModeTests.swift:25: failed - Reached 1
-
-
+
+
-
-
-
-
+
+
+
+
diff --git a/test/testdata/ios_xml_output.golden b/test/testdata/ios_xml_output.golden
index 804515dd..d53e11e9 100644
--- a/test/testdata/ios_xml_output.golden
+++ b/test/testdata/ios_xml_output.golden
@@ -1,40 +1,40 @@
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
/Users/vagrant/git/BitriseApp/BitriseAppUITests/BitriseOMUITests.swift:70 - XCTAssertTrue failed - No session found
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/testreport/test_report.go b/test/testreport/test_report.go
index 9059ddb0..31faa430 100644
--- a/test/testreport/test_report.go
+++ b/test/testreport/test_report.go
@@ -15,34 +15,53 @@ type TestSuite struct {
Name string `xml:"name,attr"`
Tests int `xml:"tests,attr"`
Failures int `xml:"failures,attr"`
+ Errors int `xml:"errors,attr"`
Skipped int `xml:"skipped,attr"`
+ Assertions int `xml:"assertions,attr,omitempty"`
Time float64 `xml:"time,attr"`
- TestCases []TestCase `xml:"testcase"`
- TestSuites []TestSuite `xml:"testsuite"`
+ Timestamp string `xml:"timestamp,attr,omitempty"`
+ File string `xml:"file,attr,omitempty"`
+ TestCases []TestCase `xml:"testcase,omitempty"`
+ TestSuites []TestSuite `xml:"testsuite,omitempty"`
}
type TestCase struct {
XMLName xml.Name `xml:"testcase"`
// ConfigurationHash is used to distinguish the same test case runs,
// performed with different build configurations (e.g., Debug vs. Release) or different devices/simulators
- ConfigurationHash string `xml:"configuration-hash,attr"`
- Name string `xml:"name,attr"`
- ClassName string `xml:"classname,attr"`
- Time float64 `xml:"time,attr"`
- // TODO: Currently a JUnit report's TestCase.Error and TestCase.SystemErr is merged into TestCase.Failure.Value field,
- // this way test execution errors are not distinguished from test failures.
- Failure *Failure `xml:"failure,omitempty"`
- Skipped *Skipped `xml:"skipped,omitempty"`
- Properties *Properties `xml:"properties,omitempty"`
+ ConfigurationHash string `xml:"configuration-hash,attr,omitempty"`
+ Name string `xml:"name,attr"`
+ ClassName string `xml:"classname,attr"`
+ Assertions int `xml:"assertions,attr,omitempty"`
+ Time float64 `xml:"time,attr"`
+ File string `xml:"file,attr,omitempty"`
+ Line int `xml:"line,attr,omitempty"`
+ Failure *Failure `xml:"failure,omitempty"`
+ Error *Error `xml:"error,omitempty"`
+ Skipped *Skipped `xml:"skipped,omitempty"`
+ Properties *Properties `xml:"properties,omitempty"`
+ SystemOut *SystemOut `xml:"system-out,omitempty"`
+ SystemErr *SystemErr `xml:"system-err,omitempty"`
}
type Failure struct {
XMLName xml.Name `xml:"failure,omitempty"`
+ Type string `xml:"type,attr,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
+ Value string `xml:",chardata"`
+}
+
+type Error struct {
+ XMLName xml.Name `xml:"error,omitempty"`
+ Type string `xml:"type,attr,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
Value string `xml:",chardata"`
}
type Skipped struct {
XMLName xml.Name `xml:"skipped,omitempty"`
+ Message string `xml:"message,attr,omitempty"`
+ Value string `xml:",chardata"`
}
type Property struct {
@@ -55,3 +74,13 @@ type Properties struct {
XMLName xml.Name `xml:"properties"`
Property []Property `xml:"property"`
}
+
+type SystemOut struct {
+ XMLName xml.Name `xml:"system-out,omitempty"`
+ Value string `xml:",chardata"`
+}
+
+type SystemErr struct {
+ XMLName xml.Name `xml:"system-err,omitempty"`
+ Value string `xml:",chardata"`
+}