本文へスキップ
BecomeCoder

Goコース · 第8章 実務のGo · レッスン32

テスト ― testing パッケージと go test

ローカル実施

導入

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チームでの一般的な進め方です。