導入
Go は標準ライブラリにテストの仕組みが最初から組み込まれています。追加のフレームワークをインストールしなくても、go test コマンドひとつでテストを実行できます。「テストを書く文化」が言語レベルで根付いているのが Go の特徴です。
説明
テスト対象の関数と同じパッケージに、ファイル名を _test.go で終わらせたファイルを作ります。
// calc.go
package calc
func Add(a, b int) int {
return a + b
}
// calc_test.go
package calc
import "testing"
func TestAdd(t *testing.T) {
got := Add(2, 3)
want := 5
if got != want {
t.Errorf("Add(2, 3) = %d, want %d", got, want)
}
}
- テスト関数は
Testで始まり、*testing.Tを1つ引数に取るという決まりがあります(func TestXxx(t *testing.T))。 - 期待どおりでなければ
t.Errorf(...)でその内容を報告します。t.Errorfはテストを失敗として記録しつつ処理を続ける(即座に止めたいときはt.Fatalf)。 - ターミナルで
go test ./...を実行すると、パッケージ内のすべてのテストが走ります。
同じ関数を複数の入力パターンでテストしたいときは、テーブル駆動テストという書き方が定番です。
func TestAddTable(t *testing.T) {
cases := []struct {
a, b, want int
}{
{1, 2, 3},
{0, 0, 0},
{-1, 1, 0},
}
for _, c := range cases {
got := Add(c.a, c.b)
if got != c.want {
t.Errorf("Add(%d, %d) = %d, want %d", c.a, c.b, got, c.want)
}
}
}
- テストしたい「入力と期待値の組」をスライス(テーブル)にまとめ、
forで1件ずつ回す。 - ケースを増やしたいときは、テーブルに1行足すだけでよく、テストのロジック自体は増やさずに済みます。
実務では、go test -v(詳細表示)や go test -cover(カバレッジ計測)もよく使われます。「新しい関数を書いたら、同じ変更で _test.go も書く」がGoチームでの一般的な進め方です。