mirror of
https://github.com/jstemmer/go-junit-report.git
synced 2025-04-06 13:38:07 -05:00
Merge pull request #45 from posener/build-error
Fail package in case of build error
This commit is contained in:
commit
e02a3f88c0
@ -21,7 +21,7 @@ go-junit-report reads the `go test` verbose output from standard in and writes
|
|||||||
junit compatible XML to standard out.
|
junit compatible XML to standard out.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test -v | go-junit-report > report.xml
|
go test -v 2>&1 | go-junit-report > report.xml
|
||||||
```
|
```
|
||||||
|
|
||||||
[travis-badge]: https://travis-ci.org/jstemmer/go-junit-report.svg
|
[travis-badge]: https://travis-ci.org/jstemmer/go-junit-report.svg
|
||||||
|
@ -487,6 +487,64 @@ var testCases = []TestCase{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "13-syntax-error.txt",
|
||||||
|
reportName: "13-report.xml",
|
||||||
|
report: &parser.Report{
|
||||||
|
Packages: []parser.Package{
|
||||||
|
{
|
||||||
|
Name: "package/name/passing1",
|
||||||
|
Time: 100,
|
||||||
|
Tests: []*parser.Test{
|
||||||
|
{
|
||||||
|
Name: "TestA",
|
||||||
|
Time: 100,
|
||||||
|
Result: parser.PASS,
|
||||||
|
Output: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "package/name/passing2",
|
||||||
|
Time: 100,
|
||||||
|
Tests: []*parser.Test{
|
||||||
|
{
|
||||||
|
Name: "TestB",
|
||||||
|
Time: 100,
|
||||||
|
Result: parser.PASS,
|
||||||
|
Output: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "package/name/failing1",
|
||||||
|
Tests: []*parser.Test{
|
||||||
|
{
|
||||||
|
Name: "build failed",
|
||||||
|
Time: 0,
|
||||||
|
Result: parser.FAIL,
|
||||||
|
Output: []string{
|
||||||
|
"failing1/failing_test.go:15: undefined: x",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "package/name/failing2",
|
||||||
|
Tests: []*parser.Test{
|
||||||
|
{
|
||||||
|
Name: "build failed",
|
||||||
|
Time: 0,
|
||||||
|
Result: parser.FAIL,
|
||||||
|
Output: []string{
|
||||||
|
"failing2/another_failing_test.go:20: undefined: y",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParser(t *testing.T) {
|
func TestParser(t *testing.T) {
|
||||||
|
@ -42,7 +42,7 @@ type Test struct {
|
|||||||
var (
|
var (
|
||||||
regexStatus = regexp.MustCompile(`^\s*--- (PASS|FAIL|SKIP): (.+) \((\d+\.\d+)(?: seconds|s)\)$`)
|
regexStatus = regexp.MustCompile(`^\s*--- (PASS|FAIL|SKIP): (.+) \((\d+\.\d+)(?: seconds|s)\)$`)
|
||||||
regexCoverage = regexp.MustCompile(`^coverage:\s+(\d+\.\d+)%\s+of\s+statements$`)
|
regexCoverage = regexp.MustCompile(`^coverage:\s+(\d+\.\d+)%\s+of\s+statements$`)
|
||||||
regexResult = regexp.MustCompile(`^(ok|FAIL)\s+(.+)\s(\d+\.\d+)s(?:\s+coverage:\s+(\d+\.\d+)%\s+of\s+statements)?$`)
|
regexResult = regexp.MustCompile(`^(ok|FAIL)\s+([^ ]+)\s+(?:(\d+\.\d+)s|(\[build failed]))(?:\s+coverage:\s+(\d+\.\d+)%\sof\sstatements)?$`)
|
||||||
regexOutput = regexp.MustCompile(`( )*\t(.*)`)
|
regexOutput = regexp.MustCompile(`( )*\t(.*)`)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,6 +66,12 @@ func Parse(r io.Reader, pkgName string) (*Report, error) {
|
|||||||
// coverage percentage report for current package
|
// coverage percentage report for current package
|
||||||
var coveragePct string
|
var coveragePct string
|
||||||
|
|
||||||
|
// stores mapping between package name and output of build failures
|
||||||
|
var packageCaptures = map[string][]string{}
|
||||||
|
|
||||||
|
// the name of the package which it's build failure output is being captured
|
||||||
|
var capturedPackage string
|
||||||
|
|
||||||
// parse lines
|
// parse lines
|
||||||
for {
|
for {
|
||||||
l, _, err := reader.ReadLine()
|
l, _, err := reader.ReadLine()
|
||||||
@ -85,9 +91,21 @@ func Parse(r io.Reader, pkgName string) (*Report, error) {
|
|||||||
Result: FAIL,
|
Result: FAIL,
|
||||||
Output: make([]string, 0),
|
Output: make([]string, 0),
|
||||||
})
|
})
|
||||||
} else if matches := regexResult.FindStringSubmatch(line); len(matches) == 5 {
|
|
||||||
if matches[4] != "" {
|
// clear the current build package, so output lines won't be added to that build
|
||||||
coveragePct = matches[4]
|
capturedPackage = ""
|
||||||
|
} else if matches := regexResult.FindStringSubmatch(line); len(matches) == 6 {
|
||||||
|
if matches[5] != "" {
|
||||||
|
coveragePct = matches[5]
|
||||||
|
}
|
||||||
|
if matches[4] == "[build failed]" {
|
||||||
|
// the build of the package failed, inject a dummy test into the package
|
||||||
|
// which indicate about the failure and contain the failure description.
|
||||||
|
tests = append(tests, &Test{
|
||||||
|
Name: "build failed",
|
||||||
|
Result: FAIL,
|
||||||
|
Output: packageCaptures[matches[2]],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// all tests in this package are finished
|
// all tests in this package are finished
|
||||||
@ -133,6 +151,12 @@ func Parse(r io.Reader, pkgName string) (*Report, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
test.Output = append(test.Output, matches[2])
|
test.Output = append(test.Output, matches[2])
|
||||||
|
} else if strings.HasPrefix(line, "# ") {
|
||||||
|
// indicates a capture of build output of a package. set the current build package.
|
||||||
|
capturedPackage = line[2:]
|
||||||
|
} else if capturedPackage != "" {
|
||||||
|
// current line is build failure capture for the current built package
|
||||||
|
packageCaptures[capturedPackage] = append(packageCaptures[capturedPackage], line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
tests/13-report.xml
Normal file
31
tests/13-report.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite tests="1" failures="0" time="0.100" name="package/name/passing1">
|
||||||
|
<properties>
|
||||||
|
<property name="go.version" value="1.0"></property>
|
||||||
|
</properties>
|
||||||
|
<testcase classname="passing1" name="TestA" time="0.100"></testcase>
|
||||||
|
</testsuite>
|
||||||
|
<testsuite tests="1" failures="0" time="0.100" name="package/name/passing2">
|
||||||
|
<properties>
|
||||||
|
<property name="go.version" value="1.0"></property>
|
||||||
|
</properties>
|
||||||
|
<testcase classname="passing2" name="TestB" time="0.100"></testcase>
|
||||||
|
</testsuite>
|
||||||
|
<testsuite tests="1" failures="1" time="0.000" name="package/name/failing1">
|
||||||
|
<properties>
|
||||||
|
<property name="go.version" value="1.0"></property>
|
||||||
|
</properties>
|
||||||
|
<testcase classname="failing1" name="build failed" time="0.000">
|
||||||
|
<failure message="Failed" type="">failing1/failing_test.go:15: undefined: x</failure>
|
||||||
|
</testcase>
|
||||||
|
</testsuite>
|
||||||
|
<testsuite tests="1" failures="1" time="0.000" name="package/name/failing2">
|
||||||
|
<properties>
|
||||||
|
<property name="go.version" value="1.0"></property>
|
||||||
|
</properties>
|
||||||
|
<testcase classname="failing2" name="build failed" time="0.000">
|
||||||
|
<failure message="Failed" type="">failing2/another_failing_test.go:20: undefined: y</failure>
|
||||||
|
</testcase>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
14
tests/13-syntax-error.txt
Normal file
14
tests/13-syntax-error.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# package/name/failing1
|
||||||
|
failing1/failing_test.go:15: undefined: x
|
||||||
|
# package/name/failing2
|
||||||
|
failing2/another_failing_test.go:20: undefined: y
|
||||||
|
=== RUN TestA
|
||||||
|
--- PASS: TestA (0.10 seconds)
|
||||||
|
PASS
|
||||||
|
ok package/name/passing1 0.100s
|
||||||
|
=== RUN TestB
|
||||||
|
--- PASS: TestB (0.10 seconds)
|
||||||
|
PASS
|
||||||
|
ok package/name/passing2 0.100s
|
||||||
|
FAIL package/name/failing1 [build failed]
|
||||||
|
FAIL package/name/failing2 [build failed]
|
Loading…
x
Reference in New Issue
Block a user