Skip to content

Commit f81c885

Browse files
committed
cmd/go,testing: re-implement testing.Coverage
This patch revives the testing.Coverage() function, which takes a snapshot of the coverage counters within an executing "go test -cover" test binary and returns a percentage approximating the percent of statements covered so far. Fixes #59590. Change-Id: I541d47a42d71c8fb2edc473d86c8951fa80f4ab0 Reviewed-on: https://go-review.googlesource.com/c/go/+/495450 Reviewed-by: Michael Knyszek <[email protected]> Run-TryBot: Than McIntosh <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent c99d966 commit f81c885

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

src/cmd/go/internal/load/test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -932,11 +932,14 @@ func init() {
932932
func runtime_coverage_processCoverTestDir(dir string, cfile string, cmode string, cpkgs string) error
933933
934934
//go:linkname testing_registerCover2 testing.registerCover2
935-
func testing_registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error))
935+
func testing_registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64)
936936
937937
//go:linkname runtime_coverage_markProfileEmitted runtime/coverage.markProfileEmitted
938938
func runtime_coverage_markProfileEmitted(val bool)
939939
940+
//go:linkname runtime_coverage_snapshot runtime/coverage.snapshot
941+
func runtime_coverage_snapshot() float64
942+
940943
func coverTearDown(coverprofile string, gocoverdir string) (string, error) {
941944
var err error
942945
if gocoverdir == "" {
@@ -957,7 +960,7 @@ func coverTearDown(coverprofile string, gocoverdir string) (string, error) {
957960
958961
func main() {
959962
{{if .Cover}}
960-
testing_registerCover2({{printf "%q" .Cover.Mode}}, coverTearDown)
963+
testing_registerCover2({{printf "%q" .Cover.Mode}}, coverTearDown, runtime_coverage_snapshot)
961964
{{end}}
962965
m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, fuzzTargets, examples)
963966
{{with .TestMain}}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
# Rudimentary test of testing.Coverage().
3+
4+
[short] skip
5+
[!GOEXPERIMENT:coverageredesign] skip
6+
7+
# Simple test.
8+
go test -v -cover -count=1
9+
10+
# Make sure test still passes when test executable is built and
11+
# run outside the go command.
12+
go test -c -o t.exe -cover
13+
exec ./t.exe
14+
15+
-- go.mod --
16+
module hello
17+
18+
go 1.20
19+
-- hello.go --
20+
package hello
21+
22+
func Hello() {
23+
println("hello")
24+
}
25+
26+
// contents not especially interesting, just need some code
27+
func foo(n int) int {
28+
t := 0
29+
for i := 0; i < n; i++ {
30+
for j := 0; j < i; j++ {
31+
t += i ^ j
32+
if t == 1010101 {
33+
break
34+
}
35+
}
36+
}
37+
return t
38+
}
39+
40+
-- hello_test.go --
41+
package hello
42+
43+
import "testing"
44+
45+
func TestTestCoverage(t *testing.T) {
46+
Hello()
47+
C1 := testing.Coverage()
48+
foo(29)
49+
C2 := testing.Coverage()
50+
if C1 == 0.0 || C2 == 0.0 {
51+
t.Errorf("unexpected zero values C1=%f C2=%f", C1, C2)
52+
}
53+
if C1 >= C2 {
54+
t.Errorf("testing.Coverage() not monotonically increasing C1=%f C2=%f", C1, C2)
55+
}
56+
}
57+

src/testing/cover.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ type Cover struct {
4747
// It is not a replacement for the reports generated by 'go test -cover' and
4848
// 'go tool cover'.
4949
func Coverage() float64 {
50+
if goexperiment.CoverageRedesign {
51+
return coverage2()
52+
}
5053
var n, d int64
5154
for _, counters := range cover.Counters {
5255
for i := range counters {

src/testing/newcover.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@ import (
1515
// cover2 variable stores the current coverage mode and a
1616
// tear-down function to be called at the end of the testing run.
1717
var cover2 struct {
18-
mode string
19-
tearDown func(coverprofile string, gocoverdir string) (string, error)
18+
mode string
19+
tearDown func(coverprofile string, gocoverdir string) (string, error)
20+
snapshotcov func() float64
2021
}
2122

2223
// registerCover2 is invoked during "go test -cover" runs by the test harness
2324
// code in _testmain.go; it is used to record a 'tear down' function
2425
// (to be called when the test is complete) and the coverage mode.
25-
func registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error)) {
26+
func registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64) {
2627
cover2.mode = mode
2728
cover2.tearDown = tearDown
29+
cover2.snapshotcov = snapcov
2830
}
2931

3032
// coverReport2 invokes a callback in _testmain.go that will
@@ -46,3 +48,12 @@ func coverReport2() {
4648
func testGoCoverDir() string {
4749
return *gocoverdir
4850
}
51+
52+
// coverage2 returns a rough "coverage percentage so far"
53+
// number to support the testing.Coverage() function.
54+
func coverage2() float64 {
55+
if cover2.mode == "" {
56+
return 0.0
57+
}
58+
return cover2.snapshotcov()
59+
}

0 commit comments

Comments
 (0)