From aa338e174a99b9590671459e7bbc13ce0af0a267 Mon Sep 17 00:00:00 2001 From: Ventzilla Date: Wed, 16 Apr 2025 16:39:41 -0700 Subject: [PATCH] fix(junit): Correctly identify panicking test in JUnit report --- internal/junitxml/report.go | 8 +++++++- testjson/execution.go | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/internal/junitxml/report.go b/internal/junitxml/report.go index c5db2ccc..ae846535 100644 --- a/internal/junitxml/report.go +++ b/internal/junitxml/report.go @@ -189,8 +189,14 @@ func packageTestCases(pkg *testjson.Package, formatClassname FormatFunc) []JUnit for _, tc := range pkg.Failed { jtc := newJUnitTestCase(tc, formatClassname) + msg := "Failed" + // Check if this specific test case is the one identified as panicking + // within the package. If so, mark its failure message specifically as "Panic". + if pkg.Panicked() && tc.ID == pkg.PanickingTestID() { + msg = "Panic" + } jtc.Failure = &JUnitFailure{ - Message: "Failed", + Message: msg, Contents: strings.Join(pkg.OutputLines(tc), ""), } cases = append(cases, jtc) diff --git a/testjson/execution.go b/testjson/execution.go index b651d712..663ad240 100644 --- a/testjson/execution.go +++ b/testjson/execution.go @@ -108,6 +108,10 @@ type Package struct { // shuffleSeed is the seed used to shuffle the tests. The value is set when // tests are run with -shuffle shuffleSeed string + // panickingTestID stores the ID of the test that panicked, if known. + // ID 0 means the panic was not associated with a specific test (e.g., + // package-level panic or panic occurred before test ID could be determined). + panickingTestID int // testTimeoutPanicInTest stores the name of a test that received the panic // output caused by a test timeout. This is necessary to work around a race @@ -197,6 +201,12 @@ func (p *Package) OutputLines(tc TestCase) []string { func (p *Package) addOutput(id int, output string) { if strings.HasPrefix(output, "panic: ") { p.panicked = true + // Only record the test ID if it's not a package-level panic (id 0) + // and if we haven't already recorded a panicking test ID for this package. + // This helps pinpoint the first test that triggered a panic. + if id != 0 && p.panickingTestID == 0 { + p.panickingTestID = id + } } p.output[id] = append(p.output[id], output) } @@ -880,3 +890,14 @@ func (s noopHandler) Event(TestEvent, *Execution) error { func (s noopHandler) Err(string) error { return nil } + +// Panicked returns true if the package or one of its tests panicked. +func (p *Package) Panicked() bool { + return p.panicked +} + +// PanickingTestID returns the ID of the test case that panicked, or 0 if the +// panic was not associated with a specific test case. +func (p *Package) PanickingTestID() int { + return p.panickingTestID +}