自分のPRを見て思う、TableDrivenTestsの良さ
jd
という、commandline utility and Go library for diffing and patching JSON values
なライブラリにTableDrivenTestsを導入したので、その良さを主観的にまとめておこうと思う。
まずは、実際にdiffの一部を見てみる。
https://github.com/josephburnett/jd/pull/29/files#diff-a0a78ab7b3426f60e7b758b565129777bdcef35e95a490999a0ff377389576d1R83
before
ctx := newTestContext(t) checkDiff(ctx, `[]`, `[]`) checkDiff(ctx, `[[]]`, `[[1]]`, `@ [0,0]`, `+ 1`) checkDiff(ctx, `[1,2,3]`, `[1,null,3]`, `@ [1]`, `- 2`, `+ null`) checkDiff(ctx, `[]`, `[3,4,5]`, `@ [0]`, `+ 3`, `@ [1]`, `+ 4`, `@ [2]`, `+ 5`)
after
ctx := newTestContext(t) tests := []struct { context *testContext a string b string diffLines []string }{ {ctx, `[]`, `[]`, []string {}}, {ctx, `[[]]`, `[[1]]`, []string { `@ [0,0]`, `+ 1`, }, }, {ctx, `[1,2,3]`, `[1,null,3]`, []string { `@ [1]`, `- 2`, `+ null`, }, }, {ctx, `[]`, `[3,4,5]`, []string { `@ [0]`, `+ 3`, `@ [1]`, `+ 4`, `@ [2]`, `+ 5`, }, }, } for _, tt := range tests { checkDiff(tt.context, tt.a, tt.b, tt.diffLines...) }
よいと思うところを2つ書く。
関数呼び出しが冗長でなくなった
beforeとafterで関数を呼び出す回数は変わらないが、afterはループの中で呼び出しているので、パッと見て冗長な表現にはなっていない。
func TestArrayDiff(t *testing.T) {
のなかのテストなので、checkDiff
を何回も呼び出している(ように見える)のは多少くどい。
関数の引数が宣言的になった
checkDiff
関数は、func checkDiff(ctx *testContext, a, b string, diffLines ...string) {
という形で引数を取る。
jd/common_test.go at d1d4edfee5375f88c1155ef55158597fb8488751 · josephburnett/jd · GitHub
beforeでは、どこからがdiffLines
が多少わかりにくくなっているが、afterでは、[]string
でまとめているため、checkDiff
に何がどの引数で渡されるのかが分かりやすくなっている。
{ context *testContext a string b string diffLines []string }
また、上のように、テストのはじめに宣言できることで、可読性が非常に高くなっている。
今回のようにbeforeがあの状態だったら、TableDrivenTestを導入しない手はないのではないかと思う。
割といい変更がだせたので自画自賛タイトルをつけてみた。