什么是单元测试
单元测试(Unit Testing)是软件测试中最基础的层级, 指对程序中最小可测试单元(如函数、方法、类等)进行独立、自动化的验证, 以确认其逻辑行为是否严格符合预期设计, 用通俗点的话来说就是: 写测试代码验证逻辑代码是否有误
txt
.
├── go.mod
├── go.sum
├── main.go
└── tools
├── tools.go
└── tools_test.go
2 directories, 5 filesgo
package tools
func Sum(nums ...int) int {
result := 0
for _, num := range nums {
result += num
}
return result
}
func Avg(nums ...int) int {
count := len(nums)
// if count == 0 {
// return 0
// }
sum := Sum(nums...)
return sum / count
}go
package tools
import "testing"
// 注意命名必须是: TestXxx
// 比如被验证的的函数名是 sum, 那么测试用例就必须是 TestSum
// 注意这个函数必须有且只有一个参数 t: *testing.T
func TestSum(t *testing.T) {
result := Sum(1, 2, 3)
expected := 6
if result != expected {
t.Errorf("Sum(1, 2, 3) = %d, want %d", result, expected)
}
}
// 如果有多个测试用例, 可以在 TestSum 函数名后续增
// 加数字, 如 TestSum2, TestSum3, 表示多个测试用例
func TestSum2(t *testing.T) {
result := Sum(1, 2, 3, 4)
expected := 10
if result != expected {
t.Errorf("Sum(1, 2, 3) = %d, want %d", result, expected)
}
}
// 求平均值
func TestAvg(t *testing.T) {
result := Avg(1, 2, 3)
expected := 2
if result != expected {
t.Errorf("Avg(1, 2, 3) = %d, want %d", result, expected)
}
}
// 求平均值: 但是会有小数的情况, 自动取整, 舍弃小数部分
func TestAvg2(t *testing.T) {
result := Avg(1, 2, 3, 4)
expected := 2
if result != expected {
t.Errorf("Avg(1, 2, 3, 4) = %d, want %d", result, expected)
}
}
// 这个测试用例无法通过, 因为没有判断参数个数为0的情况
func TestAvg3(t *testing.T) {
result := Avg()
expected := 0
if result != expected {
t.Errorf("Avg() = %d, want %d", result, expected)
}
}sh
# -v 表示显示更详细的输出
# ./tools 表示找到该目录下所有 xxx_test.go 文件, 编译执行
go test -v ./tools单元测试3要素
- 模拟被测试函数所需要的数据 Given
- 将模拟的数据传递给被测试的函数 When
- 判断被测试函数的结果与预期的结果是否相符合 Then
单元测试工具库了解
- https://github.com/avelino/awesome-go?tab=readme-ov-file#testing
- https://github.com/onsi/ginkgo
- https://github.com/smartystreets/goconvey
- https://github.com/stretchr/testify
- https://github.com/uber-go/mock
使用 testing 改善测试代码
go
package tools
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSum(t *testing.T) {
result := Sum(1, 2, 3)
expected := 6
// 不要手动判断结果, 而是使用函数判断(相等/不相等/nil)
// 如果结果不是想要的结果会自动报错, 而不是手动报错
assert.Equal(t, result, expected)
}
func TestSum2(t *testing.T) {
result2 := Sum(1, 2, 3, 4)
expected2 := 10
assert.Equal(t, result2, expected2)
}
func TestAvg(t *testing.T) {
result := Avg(1, 2, 3)
expected := 2
assert.Equal(t, result, expected)
}
func TestAvg2(t *testing.T) {
result := Avg(1, 2, 3, 4)
expected := 2
assert.Equal(t, result, expected)
}
func TestAvg3(t *testing.T) {
result := Avg()
expected := 0
assert.Equal(t, result, expected)
}