cmd/go: -coverprofile with relative path uses wrong file name

trnvg8h3  于 6个月前  发布在  Go
关注(0)|答案(7)|浏览(47)

请在提交问题之前回答以下问题。谢谢!

您正在使用的Go版本是什么( go version )?

go version go1.9.1 darwin/amd64

这个问题在最新版本中是否重现?

是的

您正在使用什么操作系统和处理器架构( go env )?

macOS Sierra 10.12.6

您做了什么?

如果可能,请提供一个重现错误的食谱。
一个完整的可运行程序很好。
play.golang.org上的链接是最好的。
我试图为一个简单的应用程序生成覆盖率报告,但由于在-coverprofile输出中生成了错误的路径,无法实现。我在这里遇到了问题: Masterminds/glide#43 。我已经用一个类似于我的应用程序 backbone 的简单示例重新创建了这个问题。我正在macOS Sierra上,通过goenv安装了go1.9。

目录结构

$ tree src/
src/
├── cover.out
├── lib
│   └── foo
│       ├── Dummy.go
│       ├── SuperDummy.go
│       └── TestSuperDummy_test.go
├── main.go

Dummy.go

package foo

func HelloWorld() string {
	return  "hello world"
}

SuperDummy.go

package foo

import "fmt"

type SuperDummy struct {
	Forename string
}

func (dummy SuperDummy) SayHello() {
	fmt.Printf("Hello my name is %s!", dummy.Forename)
}

TestSuperDummy_test.go

package foo

import "testing"

func TestSuperDummy_SayHello(t *testing.T) {
	var d = SuperDummy{"Paul"}
	d.SayHello()
}

main.go

package main

import (
	"./lib/foo"
	"fmt"
)

func main() {
	var d foo.SuperDummy = foo.SuperDummy{"Patrick"}
	d.SayHello()
	fmt.Println(foo.HelloWorld())
}

src/ 目录运行 go test ./lib/foo -coverprofile=cover.out ,得到:

src$ go test ./lib/foo -coverprofile=cover.out
ok      _/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo   0.007s  coverage: 50.0% of statements
src$ cat cover.out 
mode: set
_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo/Dummy.go:3.26,5.2 1 0
_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo/SuperDummy.go:9.36,11.2 1 1

运行 go tool cover -html=cover.out 会得到错误:

src$ go tool cover -html=cover.out
cover: can't find "Dummy.go": cannot find package "_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo/" in any of:
        /Users/patrickburton/.goenv/versions/1.9.0/src/_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo (from $GOROOT)
        /Users/patrickburton/.go/src/_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo (from $GOPATH)
        /Users/patrickburton/IdeaProjects/src/_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo
2hh7jdfx

2hh7jdfx1#

我猜这可能是与使用-coverprofile时除导入路径之外的某个东西相关的错误。

nr9pn0ug

nr9pn0ug2#

你的意思是什么?你知道有什么解决方法吗?

jmo0nnb3

jmo0nnb33#

我认为我在命令行中的意思是,go test ./lib/foo -coverprofile=cover.out的参数给go test./lib/foo时,不是一个导入路径。解决方法是使用一个导入路径。无论如何,值得尝试一下。

2w3rbyxf

2w3rbyxf4#

我尝试了这个,但是覆盖工具似乎会在覆盖率数据前加上类似CWD或command-line-arguments的东西。例如,我在foo/目录下运行以下命令并得到以下结果:

foo$ go test *.go -coverprofile=cover.out
ok      command-line-arguments  0.006s  coverage: 50.0% of statements
foo$ go tool cover -html=cover.out
cover: can't find "Dummy.go": cannot find package "command-line-arguments/" in any of:
        /Users/patrickburton/.goenv/versions/1.9.1/src/command-line-arguments (from $GOROOT)
        /Users/patrickburton/.go/src/command-line-arguments (from $GOPATH)
        /Users/patrickburton/IdeaProjects/gotest-issue/src/command-line-arguments

如果你看最后一行/Users/patrickburton/IdeaProjects/gotest-issue/src/command-line-arguments,command-line-arguments甚至不在我的GOPATH中:

elimstats$ echo $GOPATH
/Users/patrickburton/.go:/Users/patrickburton/IdeaProjects:/Users/patrickburton/IdeaProjects/elimstats/src/lib/elimstats:/Users/patrickburton/IdeaProjects/elimstats/src/lib
e4yzc0pl

e4yzc0pl5#

@TheD0ctor,你有没有找到解决这个问题的方法?在1.9.5版本中仍然看到这个问题。

jv4diomz

jv4diomz6#

我也看到了这个问题,这是我的解决方法(在我的仓库目录中运行):

go test -coverprofile=c.out
sed -i "s/_$(pwd|sed 's/\//\\\//g')/./g" c.out
go tool cover -html=c.out -o=c.html
  1. 将测试覆盖率输出到 c.out
  • 使用两个sed命令:
  • 内部sed转义来自 pwd 命令的斜杠(/dirs/now/like/so)
  • 使用转义后的pwd,我们使用外部sed来查找/替换绝对路径,仅使用相对路径 ./
  • 现在 go tool cover 可以成功地将 c.out 处理成 c.html
t1qtbnec

t1qtbnec7#

FWIW this is still in this state as of go1.11
$ go test -v -coverprofile=coverage.out -covermode=count ./...
...
coverage: 70.0% of statements
$ more coverage.out
mode: count
/home/me/scripts/git/parsembox/parsembox.go:31.38,36.2 1 10
/home/me/scripts/git/parsembox/parsembox.go:38.34,42.2 3 15
For some projects I've had this in a githook:
go test -coverprofile=coverage.out sed -i "s/_$(pwd|sed 's/\//\\\//g')/./g" coverage.out
which kinda stinks, but works :(
note: the sed recipe acopy/paste problem... fixed, I hope :)

相关问题