Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
Adding capability to write xunit report with the task suites and results #25
Open
sergiocazzolato
wants to merge 8 commits into
snapcore:master
from
sergiocazzolato:add_xunit_report_capability
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
dafbf61
Adding capability to write xunit report with the task suites and results
sergiocazzolato 75c9274
fix minor changes based on pull request differences
sergiocazzolato 1812b80
Adding test duration which is the time the task took to be executed a…
sergiocazzolato 9b5eee3
Adding classname to the xunit file containing the project.backend.sys…
sergiocazzolato c80ca7e
Fixing issue when the suite is inisde a tests directory such as in snapd
sergiocazzolato beee1af
Reporting the time in seconds instead of milliseconds
sergiocazzolato 8373be0
Bug fix to show as decimal the test elapsed time
sergiocazzolato f041328
Round the test elapsed time in 3 decimals
sergiocazzolato
Jump to file or symbol
Failed to load files and symbols.
140
spread/report.go
| @@ -0,0 +1,140 @@ | ||
| +package spread | ||
| + | ||
| +import ( | ||
| + "strconv" | ||
| + "time" | ||
| + | ||
| + "encoding/xml" | ||
| + "io/ioutil" | ||
| +) | ||
| + | ||
| +type XUnitTestSuites struct { | ||
| + XMLName xml.Name `xml:"testsuites"` | ||
| + Suites []*XUnitTestSuite | ||
| +} | ||
| + | ||
| +func (tss *XUnitTestSuites) addSuite(suite *XUnitTestSuite) { | ||
| + tss.Suites = append(tss.Suites, suite) | ||
| +} | ||
| + | ||
| +func (tss *XUnitTestSuites) getSuite(suiteName string) *XUnitTestSuite { | ||
| + for _, s := range tss.Suites { | ||
| + if s.Name == suiteName { | ||
| + return s | ||
| + } | ||
| + } | ||
| + suite := NewTestSuite(suiteName) | ||
| + | ||
| + tss.addSuite(suite) | ||
| + return suite | ||
| +} | ||
| + | ||
| +type XUnitTestSuite struct { | ||
| + XMLName xml.Name `xml:"testsuite"` | ||
| + Tests int `xml:"tests,attr"` | ||
| + Failures int `xml:"failures,attr"` | ||
| + Time string `xml:"time,attr"` | ||
| + Name string `xml:"name,attr"` | ||
| + Properties []*XUnitProperty `xml:"properties>property,omitempty"` | ||
| + TestCases []*XUnitTestCase | ||
| +} | ||
| + | ||
| +func NewTestSuite(suiteName string) *XUnitTestSuite { | ||
| + return &XUnitTestSuite{ | ||
| + Tests: 0, | ||
| + Failures: 0, | ||
| + Time: "", | ||
| + Name: suiteName, | ||
| + Properties: []*XUnitProperty{}, | ||
| + TestCases: []*XUnitTestCase{}, | ||
| + } | ||
| +} | ||
| + | ||
| +func (ts *XUnitTestSuite) addTest(test *XUnitTestCase) { | ||
| + if test.Failure != nil { | ||
| + ts.Failures += 1 | ||
| + } | ||
| + ts.Tests += 1 | ||
| + ts.TestCases = append(ts.TestCases, test) | ||
| +} | ||
| + | ||
| +type XUnitTestCase struct { | ||
| + XMLName xml.Name `xml:"testcase"` | ||
| + Classname string `xml:"classname,attr"` | ||
| + Name string `xml:"name,attr"` | ||
| + Time string `xml:"time,attr"` | ||
| + SkipMessage *XUnitSkipMessage `xml:"skipped,omitempty"` | ||
| + Failure *XUnitFailure `xml:"failure,omitempty"` | ||
| +} | ||
| + | ||
| +func NewTestCase(testName string, className string, duration time.Duration) *XUnitTestCase { | ||
| + return &XUnitTestCase{ | ||
| + Classname: className, | ||
| + Name: testName, | ||
| + Time: strconv.FormatFloat(float64(duration/time.Millisecond)/1000, 'f' , 3, 64), | ||
| + Failure: nil, | ||
| + } | ||
| +} | ||
| + | ||
| +type XUnitSkipMessage struct { | ||
| + Message string `xml:"message,attr"` | ||
| +} | ||
| + | ||
| +type XUnitProperty struct { | ||
| + Name string `xml:"name,attr"` | ||
| + Value string `xml:"value,attr"` | ||
| +} | ||
| + | ||
| +type XUnitFailure struct { | ||
| + Message string `xml:"message,attr"` | ||
| + Type string `xml:"type,attr"` | ||
| + Contents string `xml:",chardata"` | ||
| +} | ||
| + | ||
| +type XUnitReport struct { | ||
| + FileName string | ||
| + TestSuites *XUnitTestSuites | ||
| +} | ||
| + | ||
| +func NewXUnitReport(name string) XUnitReport { | ||
| + report := XUnitReport{} | ||
| + report.FileName = name | ||
| + report.TestSuites = &XUnitTestSuites{} | ||
| + return report | ||
| +} | ||
| + | ||
| +func (r XUnitReport) finish() error { | ||
| + bytes, err := xml.MarshalIndent(r.TestSuites, "", "\t") | ||
| + check(err) | ||
| + | ||
| + err = ioutil.WriteFile(r.FileName, bytes, 0644) | ||
| + check(err) | ||
| + | ||
| + return nil | ||
| +} | ||
| + | ||
| +func (r XUnitReport) addTest(suiteName string, test *XUnitTestCase) { | ||
| + suite := r.TestSuites.getSuite(suiteName) | ||
| + suite.addTest(test) | ||
| +} | ||
| + | ||
| +func (r XUnitReport) addFailedTest(suiteName string, className string, testName string, duration time.Duration) { | ||
| + testcase := NewTestCase(testName, className, duration) | ||
| + testcase.Failure = &XUnitFailure{ | ||
| + Message: "Failed", | ||
| + Type: "", | ||
| + Contents: "", | ||
| + } | ||
| + r.addTest(suiteName, testcase) | ||
| +} | ||
| + | ||
| +func (r XUnitReport) addPassedTest(suiteName string, className string, testName string, duration time.Duration) { | ||
| + testcase := NewTestCase(testName, className, duration) | ||
| + r.addTest(suiteName, testcase) | ||
| +} | ||
| + | ||
| +func check(e error) { | ||
| + if e != nil { | ||
| + panic(e) | ||
| + } | ||
| +} |