testing 包基本用法
testing 包提供了 Go 包的自动化测试支持。
基本测试函数
// math_test.go
package math
import "testing"
// 测试函数必须以 Test 开头
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Add(2, 3) = %d; want 5", result)
}
}
func TestSubtract(t *testing.T) {
result := Subtract(5, 3)
if result != 2 {
t.Errorf("Subtract(5, 3) = %d; want 2", result)
}
}
表驱动测试
package math
import "testing"
func TestMultiply(t *testing.T) {
tests := []struct {
a, b int
expected int
}{
{2, 3, 6},
{0, 5, 0},
{-2, 3, -6},
{-2, -3, 6},
}
for _, tt := range tests {
result := Multiply(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Multiply(%d, %d) = %d; want %d",
tt.a, tt.b, result, tt.expected)
}
}
}
子测试
package math
import "testing"
func TestDivide(t *testing.T) {
t.Run("正常除法", func(t *testing.T) {
result, err := Divide(10, 2)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if result != 5 {
t.Errorf("got %v, want 5", result)
}
})
t.Run("除以零", func(t *testing.T) {
_, err := Divide(10, 0)
if err == nil {
t.Error("expected error for division by zero")
}
})
}
基准测试
package math
import "testing"
// 基准测试函数以 Benchmark 开头
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(1, 2)
}
}
func BenchmarkFibonacci(b *testing.B) {
for i := 0; i < b.N; i++ {
Fibonacci(20)
}
}
// 比较不同实现的性能
func BenchmarkFibonacciMemo(b *testing.B) {
memo := make(map[int]int)
for i := 0; i < b.N; i++ {
fibMemo(20, memo)
}
}
示例测试
package math
import "fmt"
// 示例函数以 Example 开头
func ExampleAdd() {
result := Add(2, 3)
fmt.Println(result)
// Output: 5
}
func ExampleDivide() {
result, _ := Divide(10, 2)
fmt.Println(result)
// Output: 5
}
测试辅助函数
package math
import (
"path/filepath"
"runtime"
"testing"
)
// 获取测试数据路径
func testdataPath(t *testing.T, name string) string {
t.Helper() // 标记为辅助函数
_, file, _, ok := runtime.Caller(0)
if !ok {
t.Fatal("无法获取当前文件路径")
}
return filepath.Join(filepath.Dir(file), "testdata", name)
}
func TestWithFile(t *testing.T) {
path := testdataPath(t, "input.txt")
// 使用 path 进行测试...
}
并行测试
package math
import (
"testing"
"time"
)
func TestParallel(t *testing.T) {
tests := []struct {
name string
delay time.Duration
}{
{"fast", 100 * time.Millisecond},
{"slow", 500 * time.Millisecond},
}
for _, tt := range tests {
tt := tt // 捕获循环变量
t.Run(tt.name, func(t *testing.T) {
t.Parallel() // 标记为并行测试
time.Sleep(tt.delay)
})
}
}
跳过测试
package math
import (
"runtime"
"testing"
)
func TestWindowsOnly(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("此测试仅在 Windows 上运行")
}
// Windows 特定测试...
}
func TestWithShortFlag(t *testing.T) {
if testing.Short() {
t.Skip("跳过长时间运行的测试")
}
// 长时间运行的测试...
}
总结
| 测试类型 | 函数前缀 | 说明 |
|---|---|---|
| 单元测试 | Test |
基本的单元测试 |
| 基准测试 | Benchmark |
性能测试 |
| 示例测试 | Example |
文档示例测试 |
| 模糊测试 | Fuzz |
模糊测试 (Go 1.18+) |
# 运行所有测试
go test
# 显示详细输出
go test -v
# 运行基准测试
go test -bench=.
# 显示覆盖率
go test -cover
# 生成覆盖率报告
go test -coverprofile=coverage.out
go tool cover -html=coverage.out
🛒 站长推荐(京东联盟)
- 《Go 程序设计语言》(Go 语言圣经,机械工业出版社) —— Go 官方团队出品,公认入门第一书
- 《Go 语言实战》(异步图书,人民邮电出版社) —— 实战导向,面试前巩固工程手感
- 《Go 语言编程之旅:一起用 Go 做项目》(博文视点,电子工业出版社) —— 项目驱动入门,从零写出完整应用
- Keychron K1Max 矮轴机械键盘(Mac/Win 双系统,QMK/VIA 开源改键) —— 轻薄矮轴 + 开源固件,程序员桌面常客
- 罗技 MX Master 3S 无线鼠标(Flow 跨屏,静音电磁滚轮) —— 人体工学设计,写代码一整天手不酸
以上链接含京东联盟推广代码;通过链接购买本站可能获得少量佣金,不影响你的购买价格。