简体   繁体   中英

predefine test.coverprofile flag

I am analyzing code coverage using go tooling. First I create test binary

go test -coverpkg="github.com/ypapax/flags" -c

Then I run it

./flags.test -test.coverprofile=/tmp/out.out
cat /tmp/out.out

And see profile content

PASS
coverage: 100.0% of statements in github.com/ypapax/flags
mode: set
github.com/ypapax/flags/main.go:5.12,7.2 1 1

The question is: Is it possible to predefine flag -test.coverprofile=/tmp/out.out so I could run without test.coverprofile flag ./flags.test cat /tmp/out.out and still see /tmp/out.out content. My test code:

package main

import "testing"

func TestRunMain(t *testing.T) {
    main()
}

My main code:

package main

import "time"

func main(){
    time.Sleep(time.Second)
}

The full code is here:

go get github.com/ypapax/flags && cd $GOPATH/src/github.com/ypapax/flags

My question may seem weird but it may be helpful if a lot of functional tests already written which call flags.test binary and it would be nice to avoid adding -test.coverprofile to each flags.test binary call.

I see 2 possible solutions:

  1. Set -test.coverprofile inside go code. How to do it?
  2. Use bash to wrap up binary with a predefined flag. But in this case, there should not be extra files. It must be the only one flags.test with predefined -test.coverprofile flag. How to do it?

I appreciate any advice. Thanks

Update

I am trying to run @dmitris answer

package main

import (
    "io/ioutil"
    "os/exec"
    "log"
    "fmt"

    . "github.com/jteeuwen/go-bindata"
)

func main() {
    prog, err := Asset("flags.test")
    if err != nil {
        panic(err)
    }
    dest := "/tmp/flags.test" // could also use https://golang.org/pkg/io/ioutil/#TempFile
    coverProfile := "/tmp/flagstest.out"
    err = ioutil.WriteFile(dest, prog, 0755)
    if err != nil {
        panic(err)
    }
    cmd := exec.Command(dest, "-test.coverprofile", coverProfile)
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatalf("Output: %s, Error: %s", string(output), err)
    }
    fmt.Println(string(output))
    fmt.Println("Coverprofile saved to ", coverProfile)
}

Not clear from where to import Asset func on line prog, err := Asset("flags.test") . Running go build -o wrapper wrapper.go gives me

./wrapper.go:13: cannot convert "flags.test" (type string) to type bindata.Asset
./wrapper.go:13: assignment count mismatch: 2 = 1

If you have to do it, you can do the following - the idea is to pack the "original" test binary into the one that you will distribute and which will unpack the "original" and call it with the required arguments:

  • install go-bindata : go get -u github.com/jteeuwen/go-bindata/...
  • create a test executable flags.test : go test -c -cover
  • create a wrapper .go file (for example, wrapper.go): go-bindata -o wrapper.go flags.test
  • edit the wrapper.go file to add a main function to extract the binary and call it with the desired arguments:

wrapper.go

func main() {
    prog, err := Asset("flags.test")
    if err != nil {
        panic(err)
    }
    dest := "/tmp/flags.test" // could also use https://golang.org/pkg/io/ioutil/#TempFile
    coverProfile := "/tmp/flagstest.out"
    err = ioutil.WriteFile(dest, prog, 0755)
    if err != nil {
        panic(err)
    }
    cmd := exec.Command(dest, "-test.coverprofile", coverProfile)
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatalf("Output: %s, Error: %s", string(output), err)
    }
    fmt.Println(string(output))
    fmt.Println("Coverprofile saved to ", coverProfile)
}
  • compile the wrapper program for distribution: go build -o wrapper wrapper.go

Output:

$ go run wrapper.go
PASS
coverage: 100.0% of statements

Coverprofile saved to  /tmp/flagstest.out

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM