golangでアプリケーション開発が流行ってきている中でテストを書く機会も多いと思います.
その中で複数のデータセットでテストを行うと思いますが、その場合分けを変数に格納し毎回if文を書いて判別しているコードを見かけたのでこの記事を書こうと思いました.
公式wikiにも載っていますが
Writing good tests is not trivial, but in many situations a lot of ground can be covered with table-driven tests.
良いテストを書くのは簡単ではないが、多くの状況はテーブル駆動型でカバーできる。
らしいです.
最初は何も見ずにテストを書いていて分かりづらいなと感じていたらこの書き方の方が良いよと指摘をいただいたので、そんな方にはこの記事を見て欲しいなと思います.
年齢から料金を出すような関数を実装.
package sample
func FeeFromAge(age int) int {
if age <= 12 {
return 1000
} else {
return 2000
}
}
この関数に対してテストコードを実装します.
まずは単純なテスト
package sample
import "testing"
func TestFeeFromAge(t *testing.T) {
errFmt := "The judgment of fee is wrong\n"
age := 10
fee := 1000
if FeeFromAge(age) != fee {
t.Error(errFmt)
}
age = 20
fee = 2000
if FeeFromAge(age) != fee {
t.Error(errFmt)
}
}
ものすごく単純に行うとこのようなテストになるかと思います.
次にテーブルドリブンテスト.
package sample
import "testing"
func TestFeeFromAge(t *testing.T) {
cases := []struct {
age int
fee int
}{
{age: 10, fee: 1000},
{age: 20, fee: 2000},
}
for _, c := range cases {
if FeeFromAge(c.age) != c.fee {
t.Error("The judgment of fee is wrong\n")
}
}
}
慣れや好みの問題もあるかもしれませんが自分は下のテストの方が見やすく感じました.
上記の場合だと関数の中で新たに条件が追加された時にまた変数格納や条件を追加しなければなりませんが,下のテーブルドリブンテストだとデータセットを追加するだけでテスト可能です.
テストを書く時には今後自分以外の人がテストを読んだり、拡張したりすることを考えて作成します. そのためテーブルドリブンテストなら簡単に読めて拡張もし易いということでした.