no more duplication of test suites.

Parsing the test tree and deciding in the marsheller whether it is a
testcase (leaf) or a suite (non-leaf)
This commit is contained in:
Erik Brakkee 2024-11-22 20:59:23 +01:00
parent 36563f55fb
commit e20795e7b9
2 changed files with 92 additions and 62 deletions

View File

@ -9,8 +9,43 @@ import (
"path/filepath"
)
func main() {
func (t *Test) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if len(t.Tests) == 0 {
start.Name = xml.Name{Local: "testcase"}
classname := ""
if t.Parent != nil {
classname = t.Parent.Name
}
var skipped *Result
if t.Skipped > 0 {
skipped = &Result{
Message: "skipped",
}
}
var failed *Result
if t.Failures > 0 {
failed = &Result{
Message: "failed",
}
}
tc := Testcase{
Name: t.Name,
// parent class name
Classname: classname,
Time: t.Time,
Skipped: skipped,
Error: nil,
Failure: failed,
SystemOut: t.SystemOut,
}
return e.EncodeElement(tc, start)
}
type Alias Test
start.Name = xml.Name{Local: "testsuite"}
return e.EncodeElement(Alias(*t), start)
}
func main() {
/*
testsuites := Testsuites{
Time: 1.23,

View File

@ -18,15 +18,15 @@ type Testsuites struct {
Time float64 `xml:"time,attr"`
Suites []*Testsuite `xml:"testsuite,omitempty"`
Suites []*Test `xml:"testsuite,omitempty"`
}
type Testsuite struct {
type Test struct {
XMLName xml.Name `xml:"testsuite"`
// required attributes
Name string `xml:"name,attr"`
Tests int `xml:"tests,attr"`
TestCount int `xml:"tests,attr"`
Failures int `xml:"failures,attr"`
Errors int `xml:"errors,attr"`
@ -34,12 +34,13 @@ type Testsuite struct {
Disabled int `xml:"disabled,attr,omitempty"`
Package string `xml:"package,attr,omitempty"`
Skipped int `xml:"skipped,attr,omitempty"`
Time string `xml:"time,attr"`
Time float64 `xml:"time,attr"`
Timestamp time.Time `xml:"timestamp,attr,omitempty"`
Testsuites []*Testsuite `xml:"testsuite,omitempty"`
Testcases []*Testcase `xml:"testcase,omitempty"`
Tests []*Test `xml:"testsuite,omitempty"`
SystemOut string `xml:"system-out,omitempty"`
Parent *Test `xml:"-"`
}
type Result struct {
@ -60,13 +61,17 @@ type Testcase struct {
SystemOut string `xml:"system-out,omitempty"`
}
func (testsuites *Testsuites) getSuite(t time.Time, pkg string) *Testsuite {
// Looks for a test in root
func (testsuites *Testsuites) getRootSuite(t time.Time, pkg string, create bool) *Test {
for _, suite := range testsuites.Suites {
if suite.Name == pkg {
return suite
}
}
suite := Testsuite{
if !create {
return nil
}
suite := Test{
Name: pkg,
Skipped: 0,
Timestamp: t,
@ -76,62 +81,53 @@ func (testsuites *Testsuites) getSuite(t time.Time, pkg string) *Testsuite {
return &suite
}
func (suite *Testsuite) getSuite(t time.Time, name string) *Testsuite {
for _, s := range suite.Testsuites {
func (suite *Test) getSuite(t time.Time, name string) *Test {
for _, s := range suite.Tests {
if s.Name == suite.Name+"/"+name {
return s
}
}
s := Testsuite{
s := Test{
Name: suite.Name + "/" + name,
Timestamp: t,
}
suite.Testsuites = append(suite.Testsuites, &s)
suite.Tests = append(suite.Tests, &s)
return &s
}
func (suite *Testsuite) getTest(t time.Time, testname string) *Testcase {
func (suite *Test) getTest(t time.Time, testname string) *Test {
suitename := suite.Name
path := strings.Split(testname, "/")
for i := 0; i < len(path)-1; i++ {
for i := 0; i < len(path); i++ {
suite = suite.getSuite(t, path[i])
suitename = suitename + "/" + path[i]
}
testname = path[len(path)-1]
for _, test := range suite.Testcases {
if test.Name == testname {
return test
}
}
if testname == "" {
panic("Empty testcase")
}
test := Testcase{
Name: testname,
Classname: suitename,
}
suite.Testcases = append(suite.Testcases, &test)
return &test
return suite
}
func (testsuites *Testsuites) getTest(t time.Time, pkg string, testname string) *Testcase {
suite := testsuites.getSuite(t, pkg)
func (testsuites *Testsuites) getTest(t time.Time, pkg string, testname string) *Test {
suite := testsuites.getRootSuite(t, pkg, true)
test := suite.getTest(t, testname)
return test
}
func (testsuites *Testsuites) Suite(t time.Time, pkg string) {
testsuites.getSuite(t, pkg)
testsuites.getRootSuite(t, pkg, true)
}
func (testsuites *Testsuites) Test(t time.Time, pkg string, test string) {
// This can be a test suite as well
testsuites.getTest(t, pkg, test)
}
func (testsuites *Testsuites) Output(t time.Time, pkg string, test string, output string) {
if test == "" {
ts := testsuites.getSuite(t, pkg)
ts := testsuites.getRootSuite(t, pkg, true)
ts.SystemOut = ts.SystemOut + output
return
}
ts := testsuites.getRootSuite(t, pkg+"/"+test, false)
if ts != nil {
ts.SystemOut = ts.SystemOut + output
return
}
@ -143,7 +139,9 @@ func (testsuites *Testsuites) Pass(t time.Time, pkg string, test string, elapsed
if test == "" {
return
}
testsuites.getTest(t, pkg, test)
if testsuites.getRootSuite(t, pkg+"/"+test, false) != nil {
return
}
}
func (testsuites *Testsuites) Bench(t time.Time, pkg string, test string, output string, elapsed float64) {
@ -155,47 +153,44 @@ func (testsuites *Testsuites) Fail(t time.Time, pkg string, test string, elapsed
if test == "" {
return
}
if testsuites.getRootSuite(t, pkg+"/"+test, false) != nil {
return
}
tc := testsuites.getTest(t, pkg, test)
tc.Time = elapsed
tc.Failure = &Result{
Message: "failed",
}
tc.Failures = 1
}
func (testsuites *Testsuites) Skip(t time.Time, pkg string, test string) {
if test == "" {
return
}
tc := testsuites.getTest(t, pkg, test)
tc.Failure = &Result{
Message: "skipped",
if testsuites.getRootSuite(t, pkg+"/"+test, false) != nil {
return
}
tc := testsuites.getTest(t, pkg, test)
tc.Skipped = 1
}
func (suite *Testsuite) Complete() {
suite.Tests = 0
func (suite *Test) Complete() {
suite.TestCount = 0
suite.Failures = 0
suite.Errors = 0
suite.Disabled = 0
suite.Skipped = 0
for _, ts := range suite.Testsuites {
if len(suite.Tests) == 0 {
suite.TestCount = 1
}
for _, ts := range suite.Tests {
ts.Complete()
suite.Tests += ts.Tests
suite.TestCount += ts.TestCount
suite.Failures += ts.Failures
suite.Errors += ts.Errors
suite.Disabled += ts.Disabled
suite.Skipped += ts.Skipped
}
for _, tc := range suite.Testcases {
suite.Tests += 1
if tc.Failure != nil {
switch tc.Failure.Message {
case "skipped":
suite.Skipped++
default:
suite.Failures++
}
}
ts.Parent = suite
}
}
@ -207,7 +202,7 @@ func (testsuites *Testsuites) Complete() {
testsuites.Skipped = 0
for _, ts := range testsuites.Suites {
ts.Complete()
testsuites.Tests += ts.Tests
testsuites.Tests += ts.TestCount
testsuites.Failures += ts.Failures
testsuites.Errors += ts.Errors
testsuites.Disabled += ts.Disabled