新增測試

現在您的程式碼已經穩定(做得很好!),請新增一個測試。在開發過程中測試程式碼可以暴露您在更改時引入的 bug。在本主題中,您將為 Hello 函式新增一個測試。

Go 內建的單元測試支援讓您可以更輕鬆地邊開發邊測試。具體來說,透過使用命名約定、Go 的 testing 包和 go test 命令,您可以快速編寫和執行測試。

  1. 在 greetings 目錄下,建立一個名為 greetings_test.go 的檔案。

    將檔案命名為 _test.go 結尾會告訴 go test 命令該檔案包含測試函式。

  2. 將以下程式碼貼上到 greetings_test.go 中並儲存檔案。
    package greetings
    
    import (
        "testing"
        "regexp"
    )
    
    // TestHelloName calls greetings.Hello with a name, checking
    // for a valid return value.
    func TestHelloName(t *testing.T) {
        name := "Gladys"
        want := regexp.MustCompile(`\b`+name+`\b`)
        msg, err := Hello("Gladys")
        if !want.MatchString(msg) || err != nil {
            t.Errorf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want)
        }
    }
    
    // TestHelloEmpty calls greetings.Hello with an empty string,
    // checking for an error.
    func TestHelloEmpty(t *testing.T) {
        msg, err := Hello("")
        if msg != "" || err == nil {
            t.Errorf(`Hello("") = %q, %v, want "", error`, msg, err)
        }
    }
    

    在此程式碼中,您

    • 在與您要測試的程式碼相同的包中實現測試函式。
    • 建立兩個測試函式來測試 greetings.Hello 函式。測試函式名採用 TestName 的形式,其中 Name 描述了具體測試的內容。此外,測試函式接受一個指向 testing 包的 testing.T 型別的指標作為引數。您可以使用此引數的方法從測試中報告和記錄資訊。
    • 實現兩個測試
      • TestHelloName 呼叫 Hello 函式,傳入一個 name 值,該函式應該能返回一個有效的響應訊息。如果呼叫返回錯誤或意外的響應訊息(不包含您傳入的 name),您將使用 t 引數的 Errorf 方法向控制檯列印一條訊息。
      • TestHelloEmpty 使用空字串呼叫 Hello 函式。此測試旨在確認您的錯誤處理是否正常工作。如果呼叫返回非空字串或沒有錯誤,您將使用 t 引數的 Errorf 方法向控制檯列印一條訊息。
  3. 在 greetings 目錄下的命令列中,執行 go test 命令來執行測試。

    go test 命令會執行測試檔案(檔名以 _test.go 結尾)中以 Test 開頭的測試函式。您可以新增 -v 標誌以獲得詳細輸出,列出所有測試及其結果。

    測試應該會透過。

    $ go test
    PASS
    ok      example.com/greetings   0.364s
    
    $ go test -v
    === RUN   TestHelloName
    --- PASS: TestHelloName (0.00s)
    === RUN   TestHelloEmpty
    --- PASS: TestHelloEmpty (0.00s)
    PASS
    ok      example.com/greetings   0.372s
    
  4. 破壞 greetings.Hello 函式以檢視失敗的測試。

    TestHelloName 測試函式會檢查您作為 Hello 函式引數指定的 name 的返回值。要檢視失敗的測試結果,請修改 greetings.Hello 函式,使其不再包含 name。

    在 greetings/greetings.go 中,將以下程式碼貼上到 Hello 函式的原位置。請注意,高亮顯示的行更改了函式返回的值,就好像 name 引數被意外刪除一樣。

    // Hello returns a greeting for the named person.
    func Hello(name string) (string, error) {
        // If no name was given, return an error with a message.
        if name == "" {
            return name, errors.New("empty name")
        }
        // Create a message using a random format.
        // message := fmt.Sprintf(randomFormat(), name)
        message := fmt.Sprint(randomFormat())
        return message, nil
    }
    
  5. 在 greetings 目錄下的命令列中,執行 go test 來執行測試。

    這次,在不帶 -v 標誌的情況下執行 go test。輸出將僅包含失敗的測試結果,這在您有很多測試時很有用。TestHelloName 測試應該會失敗,而 TestHelloEmpty 仍然會透過。

    $ go test
    --- FAIL: TestHelloName (0.00s)
        greetings_test.go:15: Hello("Gladys") = "Hail, %v! Well met!", <nil>, want match for `\bGladys\b`, nil
    FAIL
    exit status 1
    FAIL    example.com/greetings   0.182s
    

在下一個(也是最後一個)主題中,您將學習如何編譯和安裝程式碼以在本地執行它。