Like Share Discussion Bookmark Smile

J.J. Huang   2025-03-10   Getting Started Golang 04.函式   瀏覽次數:次   DMCA.com Protection Status

Go | 了解「測試函式」應用

💬 簡介

在 Go 語言中,測試是確保程式正確性與穩定性的重要手段。Go 提供了一套簡單而強大的測試框架,讓開發者能夠方便地進行單元測試,從而提高程式的可靠性。本文將介紹 Go 語言中的測試函式應用,並探討如何編寫測試案例來提升程式質量。

圖片來源:Gophers


🔎 測試函式基礎概念

1️⃣ 什麼是測試函式?

測試函式是用來驗證程式邏輯是否正確的函式。在 Go 語言中,測試函式通常會以 Test 為前綴,並接受一個 testing.T 類型的參數。這個 T 類型提供了多種方法來報告錯誤和測試結果。

  • 範例:簡單的測試函式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package main

    import "testing"

    // 加法函式
    func Add(a, b int) int {
    return a + b
    }

    // 測試加法函式
    func TestAdd(t *testing.T) {
    result := Add(2, 3)
    if result != 5 {
    t.Errorf("Add(2, 3) failed, expected 5, got %d", result)
    }
    }
    執行測試:
    1
    go test

    📝 上述測試函式會測試 Add 函式是否正確地將兩個數字相加。若結果不正確,則會顯示錯誤訊息。

2️⃣ 測試檔案命名規則

為了使 Go 測試框架正確識別測試檔案,必須遵循以下命名規則:

  • 測試檔案的命名結尾:所有的測試檔案必須以 _test.go 作為檔案名稱的結尾。例如,對應 math.go 的測試檔案應該是 math_test.go

  • 測試函式命名規則:測試函式必須以 Test 開頭,並接受一個 *testing.T 作為參數。測試函式的名稱應該與測試的功能對應,如 TestAdd

  • 範例:

    • 主程式檔案:math.go
    • 測試檔案:math_test.go
    • 測試函式:TestAdd

3️⃣ 測試函式命名規則

Go 語言的測試函式必須以 Test 開頭,並且接受一個 *testing.T 作為參數。這是 Go 測試框架的標準規範。

  • 範例:錯誤的測試函式命名
    1
    2
    3
    func AddTest() { // 錯誤,應該以 Test 開頭
    // 測試內容
    }

    📝 測試函式命名必須遵循 Test 開頭的規範,否則測試不會被執行。


🛠 測試函式進階應用

1️⃣ 測試表格

當有多組測試資料需要檢查時,可以使用測試表格(Test Table)來編寫多個測試案例。這樣能夠讓測試更加簡潔、易於擴展。

  • 範例:使用測試表格測試加法函式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package main

    import "testing"

    // 測試加法函式
    func TestAdd(t *testing.T) {
    tests := []struct {
    a, b, expected int
    }{
    {2, 3, 5},
    {1, 1, 2},
    {5, 5, 10},
    }

    for _, tt := range tests {
    t.Run("Add", func(t *testing.T) {
    result := Add(tt.a, tt.b)
    if result != tt.expected {
    t.Errorf("Add(%d, %d) failed, expected %d, got %d", tt.a, tt.b, tt.expected, result)
    }
    })
    }
    }

    📝 這樣的測試方式可以輕鬆地擴展到更多的測試案例,而無需為每個測試編寫單獨的函式。

2️⃣ 測試覆蓋率

Go 提供了測試覆蓋率(Test Coverage)功能,可以幫助我們了解測試的覆蓋範圍。以下是如何使用測試覆蓋率的範例。

  • 執行測試並查看測試覆蓋率:

    1
    go test -cover

    📝 -cover 會顯示測試覆蓋率的百分比,幫助你了解測試的完整性。

  • 查看詳細的覆蓋率報告:

    1
    2
    go test -coverprofile=coverage.out
    go tool cover -html=coverage.out

    📝 這會生成一個 HTML 格式的報告,並顯示哪些程式碼被測試過,哪些沒有被測試過。這樣可以確保你測試到程式的各個部分,從而提高程式的穩定性。
    📝 測試覆蓋率報告可以讓你找到測試的盲點,並進行補充,保證程式的各個區塊都被充分測試。

3️⃣ 測試壓力測試(Benchmark)

測試不僅限於單元測試和功能測試,還可以用來進行壓力測試(Benchmark),以評估程式的效能。Go 提供了內建的基準測試工具 testing.B,用來測量函式的執行時間和效能。

  • 範例:測試加法函式的執行效能
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package main

    import "testing"

    // 測試加法函式的效能
    func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
    Add(2, 3)
    }
    }
    執行基準測試:
    1
    go test -bench .

    📝 b.N 是測試的次數,go test -bench . 會根據你的基準測試計算出每次執行的平均時間。基準測試幫助你了解程式效能,並能進行性能優化。


🚀 測試函式的應用場景

1️⃣ 單元測試

單元測試是測試函式最常見的應用。你可以利用測試函式來檢查每一個單獨的函式是否按預期運作,確保程式的每個部分都能夠正常運行。

  • 範例:測試計算平方根函式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package main

    import (
    "math"
    "testing"
    )

    func Sqrt(x float64) float64 {
    return math.Sqrt(x)
    }

    func TestSqrt(t *testing.T) {
    result := Sqrt(9)
    if result != 3 {
    t.Errorf("Sqrt(9) failed, expected 3, got %f", result)
    }
    }

    📝 單元測試有助於保證每個小單元(函式)能正確執行,並能在未來的程式修改中保持穩定性。

2️⃣ 整合測試

整合測試用來檢查多個模組或函式協同工作時的行為。在 Go 中,測試可以用來檢查整個系統的集成度,確保不同部分能夠順利協作。

  • 範例:測試 API 請求處理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package main

    import (
    "net/http"
    "testing"
    )

    func TestAPI(t *testing.T) {
    resp, err := http.Get("http://example.com/api/v1/resource")
    if err != nil {
    t.Fatal("API 請求失敗:", err)
    }
    if resp.StatusCode != http.StatusOK {
    t.Errorf("API 返回狀態碼錯誤,期望 %d,得到 %d", http.StatusOK, resp.StatusCode)
    }
    }

    📝 整合測試幫助我們確認不同模組間的協同效應,確保系統整體的穩定性。


⚠️ 注意事項

📌 測試輸出

當使用 t.Errorft.Fatal 時,測試框架會輸出錯誤訊息。如果測試失敗,Go 會標記測試為失敗,並顯示錯誤內容。

📌 測試邊界情況

測試應該涵蓋所有邊界情況,包括極端數值、空輸入、無效輸入等,這樣才能確保程式在所有情況下都能正常運行。

📌 執行效率

過多的測試,特別是涉及到 IO 操作的測試,可能會影響程式的執行效率。應該在測試時適當設置測試的範圍,避免過多不必要的測試運行。


🎯 總結

  • 測試函式是 Go 語言中用來檢查程式邏輯是否正確的重要工具。
  • 測試函式應該遵循命名規範,並能夠驗證程式的正確性。
  • 使用測試表格可以提高測試的可擴展性和可維護性。
  • 測試覆蓋率有助於確保程式各個部分的測試完整性。
  • 單元測試和整合測試是測試函式的兩個主要應用場景。

掌握測試函式的使用,將有助於你編寫更加健壯和可靠的 Go 程式碼。

最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。


註:以上參考了
Go