基本測試模式#
func TestDivide(t *testing.T) {
result, err := Divide(10, 2)
// 使用 t.Error/t.Errorf 報告錯誤(繼續執行)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if result != 5 {
t.Errorf("Divide(10, 2) = %f; want 5", result)
}
// 使用 t.Fatal/t.Fatalf 報告致命錯誤(停止執行)
_, err = Divide(10, 0)
if err == nil {
t.Fatal("expected error for division by zero")
}
}表格驅動測試#
這是 Go 社群推薦的測試模式:
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"positive numbers", 2, 3, 5},
{"negative numbers", -2, -3, -5},
{"mixed numbers", -2, 3, 1},
{"zeros", 0, 0, 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Add(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Add(%d, %d) = %d; want %d",
tt.a, tt.b, result, tt.expected)
}
})
}
}使用
t.Run()建立子測試的好處:
- 每個測試案例獨立執行
- 可以個別執行特定案例
- 錯誤訊息更清晰
測試輔助函式#
// 使用 t.Helper() 標記輔助函式
func assertEqual(t *testing.T, got, want int) {
t.Helper() // 讓錯誤報告指向呼叫者
if got != want {
t.Errorf("got %d; want %d", got, want)
}
}
func TestWithHelper(t *testing.T) {
result := Add(2, 3)
assertEqual(t, result, 5) // 錯誤會報告這一行
}測試設定與清理#
func TestMain(m *testing.M) {
// 全域設定(所有測試前執行一次)
setup()
code := m.Run() // 執行所有測試
// 全域清理(所有測試後執行一次)
teardown()
os.Exit(code)
}
func TestWithCleanup(t *testing.T) {
// 單一測試的清理
t.Cleanup(func() {
// 測試結束時執行
cleanup()
})
// 測試邏輯
}建立臨時測試目錄
func TestFileOperations(t *testing.T) {
// 建立臨時目錄(測試結束後自動刪除)
tempDir := t.TempDir()
// 在臨時目錄中建立測試檔案
testFile := filepath.Join(tempDir, "test.txt")
os.WriteFile(testFile, []byte("test content"), 0644)
// 測試檔案操作
content, err := os.ReadFile(testFile)
if err != nil {
t.Fatal(err)
}
if string(content) != "test content" {
t.Error("content mismatch")
}
}