Skip to content

Commit

Permalink
Handle -coverprofile flag (#355)
Browse files Browse the repository at this point in the history
* Handle -coverprofile flag

Fixes #346

* Add tool for easier contribution

* Cast byte[], otherwise failure will be displayed as array of bytes, not very useful

* Fix combine not finding files if coverProfile was set

* Add test for recursive coverage

* Fix test imports to point to correct subpackages

* Add test for cover profile in parallel mode
  • Loading branch information
Alexey Soshin authored and onsi committed Jul 21, 2017
1 parent 9eda700 commit 43392d5
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 8 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
TODO
tmp/**/*
*.coverprofile
.vscode
.vscode
.idea/
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,9 @@ Go explore!
## License

Ginkgo is MIT-Licensed

## Contributing

Since Ginkgo tests also internal packages, when you fork, you'll have to replace imports with your repository.<br />
Use `before_pr.sh` for that<br />
After you finished your changes and before you push your pull request, use `after_pr.sh` to revert those changes
13 changes: 13 additions & 0 deletions before_pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Take current path
path=$(pwd)

# Split it
IFS='\/'; arrIN=($path); unset IFS;

# Find directory before ginkgo
len=${#arrIN[@]}

userDir=${arrIN[$len-2]}

# Replace onsi with userdir
find . -type f -name '*.go' -exec sed -i '' s/github.com\\/onsi\\/ginkgo\\/internal/github.com\\/$userDir\\/ginkgo\\/internal/ {} +
47 changes: 41 additions & 6 deletions ginkgo/testrunner/test_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,14 +387,30 @@ func (t *TestRunner) runParallelGinkgoSuite() RunResult {
return res
}

const CoverProfileSuffix = ".coverprofile"

func (t *TestRunner) cmd(ginkgoArgs []string, stream io.Writer, node int) *exec.Cmd {
args := []string{"--test.timeout=" + t.timeout.String()}
if *t.goOpts["cover"].(*bool) || *t.goOpts["coverpkg"].(*string) != "" || *t.goOpts["covermode"].(*string) != "" {
coverprofile := "--test.coverprofile=" + t.Suite.PackageName + ".coverprofile"

coverMode := *t.goOpts["covermode"].(*string)
coverPackage := *t.goOpts["coverpkg"].(*string)
cover := *t.goOpts["cover"].(*bool)
coverProfile := *t.goOpts["coverprofile"].(*string)

if cover || coverPackage != "" || coverMode != "" {
testCoverProfile := "--test.coverprofile="

// Set default name for coverage results
if coverProfile == "" {
testCoverProfile += t.Suite.PackageName + CoverProfileSuffix
} else {
testCoverProfile += coverProfile
}

if t.numCPU > 1 {
coverprofile = fmt.Sprintf("%s.%d", coverprofile, node)
testCoverProfile = fmt.Sprintf("%s.%d", testCoverProfile, node)
}
args = append(args, coverprofile)
args = append(args, testCoverProfile)
}

args = append(args, ginkgoArgs...)
Expand Down Expand Up @@ -447,8 +463,17 @@ func (t *TestRunner) run(cmd *exec.Cmd, completions chan RunResult) RunResult {

func (t *TestRunner) combineCoverprofiles() {
profiles := []string{}

coverProfile := *t.goOpts["coverprofile"].(*string)

for cpu := 1; cpu <= t.numCPU; cpu++ {
coverFile := fmt.Sprintf("%s.coverprofile.%d", t.Suite.PackageName, cpu)
var coverFile string
if coverProfile == "" {
coverFile = fmt.Sprintf("%s%s.%d", t.Suite.PackageName, CoverProfileSuffix, cpu)
} else {
coverFile = fmt.Sprintf("%s.%d", coverProfile, cpu)
}

coverFile = filepath.Join(t.Suite.Path, coverFile)
coverProfile, err := ioutil.ReadFile(coverFile)
os.Remove(coverFile)
Expand Down Expand Up @@ -484,5 +509,15 @@ func (t *TestRunner) combineCoverprofiles() {
output = append(output, fmt.Sprintf("%s %d", line, lines[line]))
}
finalOutput := strings.Join(output, "\n")
ioutil.WriteFile(filepath.Join(t.Suite.Path, fmt.Sprintf("%s.coverprofile", t.Suite.PackageName)), []byte(finalOutput), 0666)

finalFilename := ""

if coverProfile != "" {
finalFilename = coverProfile
} else {
finalFilename = fmt.Sprintf("%s%s", t.Suite.PackageName, CoverProfileSuffix)
}

ioutil.WriteFile(filepath.Join(t.Suite.Path, finalFilename),
[]byte(finalOutput), 0666)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package first_package

func A() string {
return "A"
}

func B() string {
return "B"
}

func C() string {
return "C"
}

func D() string {
return "D"
}

func E() string {
return "untested"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package first_package_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"testing"
)

func TestCoverageFixture(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "CombinedFixture First Suite")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package first_package_test

import (
. "github.com/onsi/ginkgo/integration/_fixtures/combined_coverage_fixture/first_package"
. "github.com/onsi/ginkgo/integration/_fixtures/combined_coverage_fixture/first_package/external_coverage_fixture"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("CoverageFixture", func() {
It("should test A", func() {
Ω(A()).Should(Equal("A"))
})

It("should test B", func() {
Ω(B()).Should(Equal("B"))
})

It("should test C", func() {
Ω(C()).Should(Equal("C"))
})

It("should test D", func() {
Ω(D()).Should(Equal("D"))
})

It("should test external package", func() {
Ω(Tested()).Should(Equal("tested"))
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package external_coverage

func Tested() string {
return "tested"
}

func Untested() string {
return "untested"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package second_package

func A() string {
return "A"
}

func B() string {
return "B"
}

func C() string {
return "C"
}

func D() string {
return "D"
}

func E() string {
return "E"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package second_package_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"testing"
)

func TestCoverageFixture(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "CombinedFixture Second Suite")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package second_package_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/integration/_fixtures/combined_coverage_fixture/second_package"
. "github.com/onsi/gomega"
)

var _ = Describe("CoverageFixture", func() {
It("should test A", func() {
Ω(A()).Should(Equal("A"))
})

It("should test B", func() {
Ω(B()).Should(Equal("B"))
})

It("should test C", func() {
Ω(C()).Should(Equal("C"))
})

It("should test D", func() {
Ω(D()).Should(Equal("D"))
})

It("should test E", func() {
Ω(E()).Should(Equal("E"))
})
})
49 changes: 48 additions & 1 deletion integration/coverage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
"fmt"
)

var _ = Describe("Coverage Specs", func() {
Expand All @@ -18,7 +19,7 @@ var _ = Describe("Coverage Specs", func() {
session := startGinkgo("./_fixtures/coverage_fixture", "-cover")
Eventually(session).Should(gexec.Exit(0))
output := session.Out.Contents()
Ω(output).Should(ContainSubstring("coverage: 80.0% of statements"))
Ω(string(output)).Should(ContainSubstring("coverage: 80.0% of statements"))

serialCoverProfileOutput, err := exec.Command("go", "tool", "cover", "-func=./_fixtures/coverage_fixture/coverage_fixture.coverprofile").CombinedOutput()
Ω(err).ShouldNot(HaveOccurred())
Expand Down Expand Up @@ -50,4 +51,50 @@ var _ = Describe("Coverage Specs", func() {

Ω(parallelCoverProfileOutput).Should(Equal(serialCoverProfileOutput))
})

It("validates coverprofile sets custom profile name", func() {
session := startGinkgo("./_fixtures/coverage_fixture", "-cover", "-coverprofile=coverage.txt")

Eventually(session).Should(gexec.Exit(0))

// Check that the correct file was created
_, err := os.Stat("./_fixtures/coverage_fixture/coverage.txt")

Ω(err).ShouldNot(HaveOccurred())

// Cleanup
os.RemoveAll("./_fixtures/coverage_fixture/coverage.txt")
})

It("Works in recursive mode", func() {
session := startGinkgo("./_fixtures/combined_coverage_fixture", "-r", "-cover", "-coverprofile=coverage.txt")

Eventually(session).Should(gexec.Exit(0))

packages := []string{"first_package", "second_package"}

for _, p := range packages {
coverFile := fmt.Sprintf("./_fixtures/combined_coverage_fixture/%s/coverage.txt", p)
_, err := os.Stat(coverFile)

Ω(err).ShouldNot(HaveOccurred())

// Cleanup
os.RemoveAll(coverFile)
}
})

It("Works in parallel mode", func() {
session := startGinkgo("./_fixtures/coverage_fixture", "-p", "-cover", "-coverprofile=coverage.txt")

Eventually(session).Should(gexec.Exit(0))

coverFile := "./_fixtures/coverage_fixture/coverage.txt"
_, err := os.Stat(coverFile)

Ω(err).ShouldNot(HaveOccurred())

// Cleanup
os.RemoveAll(coverFile)
})
})

0 comments on commit 43392d5

Please sign in to comment.