Go公式WikiのTable Driven Testsの日本語意訳になります。
(元記事の最終更新日: 2015/12/01 rev.7)
テーブルドリブンテストというテスト技法の説明をしています。
テーブル・ドリブン・テスト
はじめに
優れたテストを書くことはささいなことではありません。
多くの場合、テーブルドリブンテストによって多岐に渡る問題をカバーできます。
テーブルの各項目には、入力値と期待結果が含まれていて完全なテストケースになっています。
テスト内容を簡単に判別するためのテスト名のような追加情報が含まれていることもあります。
もしテストを書く際にコピー&ペーストをしている場合は、テーブルドリブンテストにリファクタリングするか、ヘルパー関数へまとめた方が良いでしょう。
テストケースが記述されたテーブルを用いて、実際のテストはそのテーブル項目全てをループ処理して各項目ごとに必要なテストを行います。
テストコードは一度だけ書かれますが全てのテーブル項目にわたって使われるため、丁寧なテストと良いエラーメッセージを書くことは理にかなっています。
テーブルドリブンテストの例
以下はfmtパッケージ
のテストコードの良い例となります。
(http://golang.org/pkg/fmt/)
var flagtests = []struct {
in string
out string
}{
{"%a", "[%a]"},
{"%-a", "[%-a]"},
{"%+a", "[%+a]"},
{"%#a", "[%#a]"},
{"% a", "[% a]"},
{"%0a", "[%0a]"},
{"%1.2a", "[%1.2a]"},
{"%-1.2a", "[%-1.2a]"},
{"%+1.2a", "[%+1.2a]"},
{"%-+1.2a", "[%+-1.2a]"},
{"%-+1.2abc", "[%+-1.2a]bc"},
{"%-1.2abc", "[%-1.2a]bc"},
}
func TestFlagParser(t *testing.T) {
var flagprinter flagPrinter
for _, tt := range flagtests {
s := Sprintf(tt.in, &flagprinter)
if s != tt.out {
t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
}
}
}
t.Errorf
によって詳細なエラーメッセージが提供されることに注目してください。
テスト関数名、入力値、結果、そして期待される結果が提供されます。
テストコードをみなくても、テストが失敗した際にどのテストがなぜ失敗したのかすぐに分かります。
t.Errorf
の呼び出しはアサーションではありません。エラーが出たとしてもテストは続行されます。たとえば整数を入力する何かのテストがあった場合に、全ての整数で失敗したのか、奇数だけで失敗したのか、それとも2のべき乗だけで失敗したのか、ということを知ることには価値があります。
参考
- http://golang.org/doc/code.html#Testing
- http://golang.org/doc/faq#assertions
- http://golang.org/doc/faq#testing_framework
- http://golang.org/pkg/testing/