运行go测试时go -cover或-coverprofile非常棒,并且可以在html或纯文本中很好地显示。但有没有api以编程方式访问它或处理文件?
答案 0 :(得分:3)
您可以尝试axw/gocov
,其中:
您可以在GoCov GUI中看到convert_statements(s []*gocov.Statement, offset int)
之类的工具使用gocov.Statement
来构建一个小型GUI:
答案 1 :(得分:1)
让我们假设我们想要从某个地方从git repo动态获取的项目获取测试覆盖率百分比(如float64),并存储在“_repos / src”下的当前文件夹中。输入将是典型的“go get”格式的项目。我们需要执行“go test -cover”,设置正确的GOPATH变量,解析输出,并提取测试覆盖率的实际百分比。使用当前的Go 1.9测试工具,下面的代码实现了这一点。
// ParseFloatPercent turns string with number% into float.
func ParseFloatPercent(s string, bitSize int) (f float64, err error) {
i := strings.Index(s, "%")
if i < 0 {
return 0, fmt.Errorf("ParseFloatPercent: percentage sign not found")
}
f, err = strconv.ParseFloat(s[:i], bitSize)
if err != nil {
return 0, err
}
return f / 100, nil
}
// GetTestCoverage returns the tests code coverage as float
// we are assuming that project is a string
// in a standard "Go get" form, for example:
// "github.com/apache/kafka"
// and, that you have cloned the repo into "_repos/src"
// of the current folder where your executable is running.
//
func GetTestCoverage(project string) (float64, error) {
cmdArgs := append([]string{"test", "-cover"}, project)
cmd := exec.Command("go", cmdArgs...)
// get the file absolute path of our main executable
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Println(err)
return 0, err
}
// set the GOPATH for tests to work
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "GOPATH="+dir+"/_repos/")
var out []byte
cmd.Stdin = nil
out, err = cmd.Output()
if err != nil {
fmt.Println(err.Error())
return 0, err
}
r := bufio.NewReader(bytes.NewReader(out))
// first line from running "go test -cover" should be in a form
// ok <project> 6.554s coverage: 64.9% of statements
// split with /t and <space> characters
line, _, err := r.ReadLine()
if err != nil {
fmt.Println(err.Error())
return 0, err
}
parts := strings.Split(string(line), " ")
if len(parts) < 6 {
return 0, errors.New("go test -cover do not report coverage correctly")
}
if parts[0] != "ok" {
return 0, errors.New("tests do not pass")
}
f, err := ParseFloatPercent(parts[3], 64)
if err != nil {
// the percentage parsing problem
return 0, err
}
return f, nil
}