1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Support for test coverage.
11 "internal/goexperiment"
16 // CoverBlock records the coverage data for a single basic block.
17 // The fields are 1-indexed, as in an editor: The opening line of
18 // the file is number 1, for example. Columns are measured
20 // NOTE: This struct is internal to the testing infrastructure and may change.
21 // It is not covered (yet) by the Go 1 compatibility guidelines.
22 type CoverBlock struct {
23 Line0 uint32 // Line number for block start.
24 Col0 uint16 // Column number for block start.
25 Line1 uint32 // Line number for block end.
26 Col1 uint16 // Column number for block end.
27 Stmts uint16 // Number of statements included in this block.
32 // Cover records information about test coverage checking.
33 // NOTE: This struct is internal to the testing infrastructure and may change.
34 // It is not covered (yet) by the Go 1 compatibility guidelines.
37 Counters map[string][]uint32
38 Blocks map[string][]CoverBlock
39 CoveredPackages string
42 // Coverage reports the current code coverage as a fraction in the range [0, 1].
43 // If coverage is not enabled, Coverage returns 0.
45 // When running a large set of sequential test cases, checking Coverage after each one
46 // can be useful for identifying which test cases exercise new code paths.
47 // It is not a replacement for the reports generated by 'go test -cover' and
49 func Coverage() float64 {
50 if goexperiment.CoverageRedesign {
54 for _, counters := range cover.Counters {
55 for i := range counters {
56 if atomic.LoadUint32(&counters[i]) > 0 {
65 return float64(n) / float64(d)
68 // RegisterCover records the coverage data accumulators for the tests.
69 // NOTE: This function is internal to the testing infrastructure and may change.
70 // It is not covered (yet) by the Go 1 compatibility guidelines.
71 func RegisterCover(c Cover) {
75 // mustBeNil checks the error and, if present, reports it and exits.
76 func mustBeNil(err error) {
78 fmt.Fprintf(os.Stderr, "testing: %s\n", err)
83 // coverReport reports the coverage percentage and writes a coverage profile if requested.
85 if goexperiment.CoverageRedesign {
91 if *coverProfile != "" {
92 f, err = os.Create(toOutputDir(*coverProfile))
94 fmt.Fprintf(f, "mode: %s\n", cover.Mode)
95 defer func() { mustBeNil(f.Close()) }()
98 var active, total int64
100 for name, counts := range cover.Counters {
101 blocks := cover.Blocks[name]
102 for i := range counts {
103 stmts := int64(blocks[i].Stmts)
105 count = atomic.LoadUint32(&counts[i]) // For -mode=atomic.
110 _, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
111 blocks[i].Line0, blocks[i].Col0,
112 blocks[i].Line1, blocks[i].Col1,
120 fmt.Println("coverage: [no statements]")
123 fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages)