LoginSignup
11
10

More than 5 years have passed since last update.

Go でパラメタライズドテストをする

Last updated at Posted at 2015-11-18

忙しい人のための結論

Go はそもそもテストコードを書くのにテスティングフレームワークを使わないのが文化として根付いているし、パラメタライズドテストも普通にループ処理で実現する。

Go でパラメタライズドテスト

先日、TDDBC 仙台 5 に行ってきたのだけど、その課題に Go で挑戦してみたときにテストをパラメタライズしたくなった。

で、それってどうやるんですかってTwitterで聞いてみたら、どうやら(予想通りと言えば予想通り)普通にそのための構造体を作ってループで処理するしかないっぽい。

つまりこんな感じになる。

// test code
func TestAdd(t *testing.T) {
    params := []struct {
        a int
        b int
        expected int
    }{
        { a: 1, b: 1, expected: 2 },
        { a: 1, b: 2, expected: 3 },
        { a: 2, b: -3, expected: -1 },
    }

    for _, p := range params {
        expected := p.expected
        actual := Add(p.a, p.b)

        if p.expected != actual {
            t.Errorf("Expected: %v, Actual: %v", expected, actual)
        }
    }
}
// product code
func Add(a int, b int) int {
    return a + b
}

途中で落ちた場合

多くのテスティングフレームワークでは 1 テストケース 1 アサーションが推奨されていて、テストケース内にアサーションが複数あった場合に前のアサーションが失敗するとそれ以降のアサーションは評価されない。

上記の Go のテストでも途中で落ちた場合にそのような挙動になるとあまり嬉しくないのだけど実際はどうなるのか。

こんな感じに変更して試してみた。

params := []struct {
    a int
    b int
    expected int
}{
    { a: 1, b: 1, expected: 2 },
    { a: 1, b: 2, expected: 2 }, // miss!
    { a: 2, b: -3, expected: 1 }, // miss!
}

結果はこんな感じ。

--- FAIL: TestAdd (0.00s)
        sum_test.go:24: Expected: 2, Actual: 3
        sum_test.go:24: Expected: 1, Actual: -1
FAIL
exit status 1
FAIL    sum_test       0.007s

2 つ目のテストケースで終わらず 3 つ目のテストまで実行され 2 つとも落ちている。
t.Errorf 内のメッセージやその一部をパラメータに含める等の工夫をすればテスト失敗時の情報量もリッチにできるし、パラメタライズドテストとして問題なく使っていけそうな気がする。

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10