引言
覆盖率报告是一种衡量测试质量的方式,它展示了代码中哪些部分已经被测试覆盖,哪些部分还没有。
1. 生成覆盖率报告
- 生成覆盖率数据:
- 使用 -coverprofile 选项来生成覆盖率数据文件。
- 示例:
go test ./... -coverprofile=coverage.out- 分析覆盖率数据:
- 使用 go tool cover 命令来分析覆盖率数据。
- 示例:
go tool cover -html=coverage.out2. 示例代码
假设我们有一个简单的数学运算包 math,其中包含两个函数 Add 和 Subtract,以及相应的测试。
// math.go
package math
func Add(x, y int) int {
return x + y
}
func Subtract(x, y int) int {
return x - y
}3. 测试代码
// math_test.go
package math
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestSubtract(t *testing.T) {
testCases := []struct {
x, y, expected int
}{
{5, 2, 3},
{-1, -1, 0},
{0, 0, 0},
{2000, 1000, 1000},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%d-%d", tc.x, tc.y), func(t *testing.T) {
assert.Equal(t, tc.expected, Subtract(tc.x, tc.y))
})
}
}
func TestAdd(t *testing.T) {
testCases := []struct {
x, y, expected int
}{
{2, 3, 5},
{-1, -1, -2},
{0, 0, 0},
{1000, 2000, 3000},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%d+%d", tc.x, tc.y), func(t *testing.T) {
assert.Equal(t, tc.expected, Add(tc.x, tc.y))
})
}
}4. 生成覆盖率报告
- 生成覆盖率数据文件:
go test ./... -coverprofile=coverage.out- 生成 HTML 报告:
go tool cover -html=coverage.out- 这将生成一个名为 coverage.html 的文件,你可以用浏览器打开查看覆盖率报告。
- 分析覆盖率报告:
- 覆盖率报告会以 HTML 形式展示代码中的每一行是否被测试覆盖。未覆盖的行将以红色显示,已覆盖的行将以绿色显示。
5. 提高覆盖率
根据覆盖率报告,你可以发现哪些部分没有被测试覆盖,并针对性地添加测试用例。例如,如果你发现某些边界条件没有被覆盖,可以添加相应的测试用例。
// math_test.go
package math
import (
"fmt"
"testing"
)
func TestAddEdgeCases(t *testing.T) {
intMin, intMax := 1, 10
testCases := []struct {
x, y, expected int
}{
{intMin, 0, intMin},
{intMax, 0, intMax},
{intMin, 1, intMin + 1},
{intMax, -1, intMax - 1},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%d+%d", tc.x, tc.y), func(t *testing.T) {
result := Add(tc.x, tc.y)
assert.Equal(t, tc.expected, result)
})
}
}
func TestSubtractEdgeCases(t *testing.T) {
intMin, intMax := 1, 10
testCases := []struct {
x, y, expected int
}{
{intMin, 0, intMin},
{intMax, 0, intMax},
{intMin, 1, intMin - 1},
{intMax, -1, intMax + 1},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%d-%d", tc.x, tc.y), func(t *testing.T) {
result := Subtract(tc.x, tc.y)
assert.Equal(t, tc.expected, result)
})
}
}6. 使用覆盖率标签
有时,你可能想跳过某些测试用例的覆盖率统计。你可以使用 //go:cover 注释来标记那些不需要计算覆盖率的代码。
// math.go
package math
//go:cover
func Add(x, y int) int {
return x + y
}
//go:cover
func Subtract(x, y int) int {
return x - y
} 