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+)
如有疑问关注公众号给我留言
wx

关注公众号

©2017-2023 鲁ICP备17023316号-1 Powered by Hugo