Diary of a Perpetual Student

Perpetual Student: A person who remains at university far beyond the normal period

Go のテーブル駆動テストは map を使って書きたい

Go 言語のプログラムのテストでは、テーブル駆動テストと呼ばれる書き方をすることが多いです。シンプルに例を挙げると以下のような形。

func TestAdd(t *testing.T) {
    cases := []struct{
        title string
        inLhs int64
        inRhs int64
        want int64
    }{
        {
            name: "1 + 1 = 2",
            inLhs: 1,
            inRhs 1,
            want: 2,
        },
    }
    for _, tt := range cases {
        t.Run(tt.title, func(t *testing.T) {
            if got := Add(tt.inLhs, tt.inRhs); got != tt.want {
                t.Errorf("want=%d, got=%d", tt.want, got)
            }
        })
    }
}

色々流派はあるのですが、僕は上のような slice ではなく、下のように map を使ってテストケースを作る方が好みです。

func TestAdd(t *testing.T) {
    cases := map[string]struct{
        inLhs int64
        inRhs int64
        want int64
    }{
        "1 + 1 = 2": {
            inLhs: 1,
            inRhs 1,
            want: 2,
        },
    }
    for title, tt := range cases {
        t.Run(title, func(t *testing.T) {
            if got := Add(tt.inLhs, tt.inRhs); got != tt.want {
                t.Errorf("want=%d, got=%d", tt.want, got)
            }
        })
    }
}

理由は2つ:

  • テストケース名が独立している方が読みやすいから
  • go の map を for した時の順序はランダムなので、順序に依存しないテストであることを保証できるから

明日はいよいよ Go Conference 2023 ですよ〜

gocon.jp

developer.hatenastaff.com