测试基本知识
单元测试
规则
在 Go 语言中,单元测试的基本规则包括:
-
所有测试文件必须以
_test.go结尾,例如example_test.go。 -
测试函数的命名格式为
TestXxx,其中Xxx是要测试的功能。例如:go
复制
func TestAdd(t *testing.T) { // 测试内容 } -
初始化逻辑通常放在
TestMain函数中,格式如下:func TestMain(m *testing.M) { // 测试前:数据装载、配置初始化等前置工作 code := m.Run() // 测试后:释放资源等收尾工作 os.Exit(code) }这种方式可以在运行所有测试之前和之后执行一些必要的设置和清理工作。
断言 assert
断言是判断测试结果是否符合预期的重要工具。Go 语言中常用的断言库是 testify,它提供了丰富的功能来简化断言操作。示例代码如下:
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestHelloTom(t *testing.T) {
left := testFunc()
right := "targetVal"
assert.Equal(t, left, right, "Expected values to be equal") // 进行断言,相等则通过,不等则报错
}
通过 assert.Equal 函数,我们可以简洁地检查两个值是否相等,并提供错误信息以便于调试。
测试覆盖率
测试覆盖率是衡量代码质量的重要指标,它反映了被测试代码在测试过程中被执行的比例。在 Go 中,可以使用以下命令查看测试覆盖率:
go test -cover
该命令会输出每个测试的覆盖率报告,帮助开发者识别未覆盖的代码部分。覆盖率的计算公式为:
覆盖率=已执行的行数总行数×100%\text{覆盖率} = \frac{\text{已执行的行数}}{\text{总行数}} \times 100%覆盖率=总行数已执行的行数×100%
Mock
Mock 技术可以帮助我们在测试中模拟依赖,进而控制测试环境。Go 语言中最常用的 Mock 库是 bouk/monkey,它允许我们在运行时修改函数的行为。使用方法如下:
- 导入 Mock 相关包,如 monkey。
- 使用
monkey.Patch()方法进行函数打桩。 - 使用
defer monkey.Unpatch()在测试结束时释放资源。
示例代码:
import (
"testing"
"github.com/bouk/monkey"
)
func TestFunc_1(t *testing.T) {
// 打桩 testFunc,使其返回固定值
monkey.Patch(testFunc, func() string {
return "mocked value"
})
defer monkey.Unpatch(testFunc) // 及时释放资源
result := testFunc()
if result != "mocked value" {
t.Errorf("expected 'mocked value', got '%s'", result)
}
}
在这个示例中,我们模拟了 testFunc 函数的返回值,从而可以在不依赖其实际实现的情况下进行测试。
使用表驱动测试
在 Go 中,表驱动测试是一种常见的测试模式,适用于需要测试多个输入和期望输出的情况。示例代码如下:
func TestAdd(t *testing.T) {
tests := []struct {
a, b, expected int
}{
{1, 2, 3},
{2, 3, 5},
{0, 0, 0},
{-1, 1, 0},
}
for _, test := range tests {
result := Add(test.a, test.b)
if result != test.expected {
t.Errorf("Add(%d, %d) = %d; want %d", test.a, test.b, result, test.expected)
}
}
}
在这个示例中,我们定义了一组测试用例,通过遍历测试用例来验证 Add 函数的正确性。
小结
通过掌握 Go 语言中单元测试的基本规则、使用断言、计算测试覆盖率以及 Mock 技术,向全沾工程师更进一步(。