支持JUnit文件路径的Golang测试运行器有哪些?

支持JUnit文件路径的Golang测试运行器有哪些? 我正在尝试在CI中运行Go测试,但go testgotestsum都没有在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或详细输出可以实现。

回到顶部