支持JUnit文件路径的Golang测试运行器有哪些?
支持JUnit文件路径的Golang测试运行器有哪些?
我正在尝试在CI中运行Go测试,但go test和gotestsum都没有在JUnit报告中的每个测试用例里添加测试文件的路径。
你知道有什么方法可以添加测试文件路径吗(例如file=)?
<testcase classname="github.com/demisto/server/repo/logicalRepo" name="TestSort" file=RELATIVE_FILEPATH time="2.070000"/>
如果没有这个信息,我就无法使用CircleCI基于时间的任务拆分功能。
更多关于支持JUnit文件路径的Golang测试运行器有哪些?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于支持JUnit文件路径的Golang测试运行器有哪些?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go测试中生成包含文件路径的JUnit报告,可以使用以下工具:
1. gotestsum + junitreport 插件
gotestsum支持通过自定义格式化器添加文件路径:
# 安装
go install gotest.tools/gotestsum@latest
# 运行测试并生成JUnit报告
gotestsum --junitfile test-results.xml --format testname -- \
-json ./... | gotestsum-junit-report --add-filepath
需要自定义junitreport处理器来添加file属性:
// custom-junit-report/main.go
package main
import (
"encoding/xml"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
type TestCase struct {
XMLName xml.Name `xml:"testcase"`
Classname string `xml:"classname,attr"`
Name string `xml:"name,attr"`
Time string `xml:"time,attr"`
File string `xml:"file,attr"`
}
type TestSuite struct {
XMLName xml.Name `xml:"testsuite"`
TestCases []TestCase `xml:"testcase"`
}
func main() {
data, _ := io.ReadAll(os.Stdin)
// 解析go test -json输出
lines := strings.Split(string(data), "\n")
var testCases []TestCase
for _, line := range lines {
if strings.Contains(line, `"Test":`) {
// 提取测试信息
// 这里需要解析JSON并提取Package和Test字段
// 然后转换为TestCase结构
}
}
output := TestSuite{TestCases: testCases}
encoder := xml.NewEncoder(os.Stdout)
encoder.Indent("", " ")
encoder.Encode(output)
}
2. go-junit-report 自定义版本
修改go-junit-report以支持file属性:
// 修改go-junit-report的testcase结构
type JUnitTestCase struct {
XMLName xml.Name `xml:"testcase"`
Classname string `xml:"classname,attr"`
Name string `xml:"name,attr"`
Time float64 `xml:"time,attr"`
File string `xml:"file,attr,omitempty"` // 添加file字段
Properties []JUnitProperty `xml:"properties>property,omitempty"`
}
// 在解析测试结果时设置File字段
func (c *JUnitTestCase) setFileFromTest(testName, packageName string) {
// 通过反射或构建标签获取测试文件路径
// 或者从go test的详细输出中提取
c.File = getTestFilePath(packageName, testName)
}
3. test2json 管道处理
使用go test的JSON输出并后处理:
# 运行测试并生成带文件路径的JUnit报告
go test -json ./... | \
go run custom-parser.go > test-results.xml
// custom-parser.go
package main
import (
"encoding/json"
"encoding/xml"
"fmt"
"io"
"os"
"path/filepath"
)
type TestEvent struct {
Time string `json:"Time"`
Action string `json:"Action"`
Package string `json:"Package"`
Test string `json:"Test"`
Elapsed float64 `json:"Elapsed"`
}
func main() {
decoder := json.NewDecoder(os.Stdin)
type TestSuite struct {
XMLName xml.Name `xml:"testsuite"`
TestCases []struct {
XMLName xml.Name `xml:"testcase"`
Classname string `xml:"classname,attr"`
Name string `xml:"name,attr"`
Time string `xml:"time,attr"`
File string `xml:"file,attr"`
} `xml:"testcase"`
}
var suite TestSuite
for {
var event TestEvent
if err := decoder.Decode(&event); err == io.EOF {
break
}
if event.Action == "pass" || event.Action == "fail" {
// 获取测试文件相对路径
relPath := getRelativeTestPath(event.Package, event.Test)
suite.TestCases = append(suite.TestCases, struct {
XMLName xml.Name `xml:"testcase"`
Classname string `xml:"classname,attr"`
Name string `xml:"name,attr"`
Time string `xml:"time,attr"`
File string `xml:"file,attr"`
}{
Classname: event.Package,
Name: event.Test,
Time: fmt.Sprintf("%f", event.Elapsed),
File: relPath,
})
}
}
output, _ := xml.MarshalIndent(suite, "", " ")
fmt.Println(string(output))
}
func getRelativeTestPath(pkg, testName string) string {
// 实现逻辑:通过包路径和测试名解析文件路径
// 例如:github.com/demisto/server/repo/logicalRepo -> repo/logicalRepo_test.go
return strings.TrimPrefix(pkg, "github.com/demisto/server/") + "_test.go"
}
4. 使用go test的-v标志和解析
go test -v ./... 2>&1 | \
go run junit-with-filepath.go > junit.xml
这些方法都需要自定义处理来提取和添加测试文件路径到JUnit报告中。目前没有现成的工具直接支持这个功能,但通过管道处理go test的JSON或详细输出可以实现。

