メインコンテンツにスキップ
モジュール 9 · レッスン 1 / 5コース内の 41/50~12 min
モジュールのレッスン (1/5)

「テスト」パッケージ

Go では、テストは stdlib の一部です。外部ライブラリや構成するフレームワークはありません。必要なのは、コードの隣にある *_test.go ファイル、いくつかの TestXxx 関数、および go test コマンドだけです。

基本的な規約

  • テスト ファイルは <something>_test.go という名前で、テスト対象のコードと 同じパッケージ (または「ブラック ボックス テスト」の場合は <name>_test パッケージ) 内に存在します。
  • テスト関数には 正確な 署名があります: func TestXxx(t *testing.T) (Xxx は大文字で始まります)。
  • testing を stdlib からインポートします。
  • いいえ assertEquals: if got != want { t.Errorf(...) } を fmt-verbs とともに使用します。
Go
// math.go
package math

func Sum(a, b int) int { return a + b }

// math_test.go
package math

import "testing"

func TestSum(t *testing.T) {
    got := Sum(2, 3)
    if got != 5 {
        t.Errorf("Sum(2,3) = %d; voglio %d", got, 5)
    }
}

次のように実行します。

Bash
go test ./...        # all packages in the module
go test -v ./pkg     # verbose: prints test names
go test -run TestSum  # only tests matching the regex

t.Error 対 t.Fatal

これらは、失敗を知らせる 2 つの基本的な動詞です。

方法効果
t.Log(args...)ログに記録されますが、失敗しません (-v または失敗時にのみ表示されます)。
t.Error(args...)ログに記録し、FAIL とマークし、テスト機能を 続行します。
t.Errorf(fmt, ...)Error のような書式設定。
t.Fatal(args...)ログに記録し、FAIL とマークし、テストを 停止します (runtime.Goexit を呼び出します)。
t.Fatalf(fmt, ...)Fatal のような書式設定。

経験則: 続行するのが意味がない場合には Fatal を使用してください (例: セットアップの失敗、差し迫った nil ポインタの逆参照)。それ以外の場合は、Error を使用すると、1 回の実行ですべての失敗を確認できます。

Go
func TestOpen(t *testing.T) {
    f, err := os.Open("fixtures/sample.txt")
    if err != nil {
        t.Fatal(err) // if it doesn't open, the next steps would fail on nil
    }
    defer f.Close()
    // ... assert on content with t.Errorf
}

t.Cleanup によるセットアップと破棄

テスト (またはサブテスト) の終了時にリソースを解放するには、defer の代わりに t.Cleanup を使用します。

Go
func TestDB(t *testing.T) {
    db := newTestDB(t)
    t.Cleanup(func() { db.Close() })
    // ... test
}

defer と比べた利点: db を作成するヘルパーはクリーンアップを内部に登録できるため、呼び出し元はクリーンアップを覚えておく必要がありません。

テストヘルパー

t.Helper() メソッドは、関数を「ヘルパー」としてマークします。テストが失敗すると、スタック トレースはヘルパー関数をスキップし、呼び出し元を直接指します。

Go
func mustParseInt(t *testing.T, s string) int {
    t.Helper()
    n, err := strconv.Atoi(s)
    if err != nil {
        t.Fatalf("parse %q: %v", s, err)
    }
    return n
}

演習

運動#go.m9.l1.e1
試行回数: 0読み込み中…

書式設定されたメッセージで t.Errorf を使用して Sum(2,3) == 5 を検証する TestSum 関数を定義します。

エディターを読み込み中…

3 回の試行後に解決策が利用可能になります

運動#go.m9.l1.e2
試行回数: 0読み込み中…

TestDiv では、Div が予期しない値を返した場合に t.Fatal を使用してテストを直ちに停止します。

エディターを読み込み中…

3 回の試行後に解決策が利用可能になります

Quiz#go.m9.l1.e3
準備完了

t.Error と t.Fatal の根本的な違いは何ですか?

Go
if err != nil {
  t.???(err)
}
回答の選択肢