Testing

Goのテストに関する情報をまとめる。

Getting Started

  • go test コマンドでテストを実行する(後述)
  • 基本的に、標準のtesting pkgを使う

関連項目:

Tips:

  • フレームワークは使わない。愚直に書く

入門ガイド:

参考:

package xのテストを書くとする。

  • package xのコードが置かれたディレクトリに *_test.go というファイルを作る
    • 先頭行は package x
  • func TestXxx(t *testing.T) という関数を作り、その中にテストコードを書く
    • t.Errorf 関数でエラーをレポート
    • エラーが報告されなければ、その関数は成功したことになる

テストの実行

See Also: goコマンド#test

モジュールのルートディレクトリで下のように実行するとよい:

go test [-v] ./...

-v を付けると個々のテストケースが見える。
サブテストの中も見える。

Spec:

  • *_test.go というファイルがテスト対象
  • ., _ で始まるファイルは無視される( _test.go も)
  • testdata というディレクトリは無視される

How-to

テーブルドリブンテスト

サブテスト(t.Run)と組み合わせる。

Examples:

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 {
		t.Run(tt.in, func(t *testing.T) {
			s := Sprintf(tt.in, &flagprinter)
			if s != tt.out {
				t.Errorf("got %q, want %q", s, tt.out)
			}
		})
	}
}

NOTE:

  • t.Parallel() を使うと並列化もできる

参考:

I/Oを伴うテスト

bytes.Bufferやstrings.Builderを使うといい。

参考:

テストデータを用意する

testdata/ というディレクトリに入れる。
これはパッケージとみなされない。

参考:

pkg

テストで使えるパッケージ。

Topics

Goで結合・統合・外部テストを書く

pkgに対する単体テスト以外のテストにもGoのtesting pkgを使うことができる。
やり方は簡単で、 package foo_testfoo_test.go を書くだけ。

package foo_test

import "testing"

func TestFoo(t *testing.T) {
    : // テストコード
}

参考:

Go Blog関連エントリ