Go の単体テスト
1. 単体テストのケース
go test は、Go の命名と関数の形式に従って書かれたテストを実行します。
パッケージ内の _test.go で終わるファイルは、テスト用のビルドに含まれます。
通常の実行ファイルには含まれないため、詳しいテストを書いても本番バイナリは大きくなりません。
次の名前には、それぞれ異なる役割があります。
Test:機能のテスト
Benchmark:性能の測定
Example:実行可能な例。ファズテストには Fuzz を使う
TestMain:パッケージのテスト全体の準備と後処理
1.1. 単体テストを書く
単体テストの例を示します。
パッケージには、次の三つの Go ファイルがあります。
1、add.go
2、add_test.go
3、main.go

add.go では、二つの整数を加える Add 関数を定義します。
add_test.go は testing を読み込み、TestAdd で Add の結果を検証し、失敗を報告します。
import "testing"
func TestAdd(t *testing.T){
re := add(1,2)
if re!= 3{
t.Errorf("add(1,2) = %d; want 3", re)
}
}
パッケージのディレクトリで go test を実行し、結果を確認します。
1.2. 時間のかかるテストを省略する
短い実行モードなどでテストを省略したい場合は、t.Skip() を使います。
go test -short は短い実行モードを有効にします。実際に省略するには、各テストで testing.Short() を調べ、t.Skip() を呼び出します。
何を時間のかかるテストとするかは、テストを書く側が決めます。
省略する例を示します。
func TestAdd(t *testing.T){
if testing.Short(){
t.Skip("skip this test")
}
// 下面是执行不到的
re := add(1,2)
if re!= 3{
t.Errorf("add(1,2) = %d; want 3", re)
}
}
testing.Short() により、通常の実行と短い実行を区別できます。
2. テーブル駆動テスト
複数の入力を試す場合は、ケースを表にまとめ、同じ検証処理を各ケースで実行します。テストコードの重複を減らせます。
テーブル駆動テストの例を示します。
import "testing"
func TestAdd(t *testing.T){
var tests = []struct{
a int
b int
want int
}{
{1,2,3},
{2,3,5},
{3,4,7},
}
for _, tt := range tests{
re := add(tt.a, tt.b)
if re!= tt.want{
t.Errorf("add(%d, %d) = %d; want %d", tt.a, tt.b, re, tt.want)
}
}
}
3. ベンチマーク
実行コストが重要な関数では、ベンチマークで性能を測定します。
ベンチマークも testing パッケージが提供します。
関数名は Benchmark で始め、その後に測定する処理の名前を付けます。
引数には *testing.B を受け取ります。
go test -bench . など、パターンを指定した go test -bench で実行します。
ベンチマークの例を示します。
import "testing"
func BenchmarkAdd(b *testing.B){
a := 123
b := 456
c := 579
for i:=0; i<b.N; i++{
if actual := add(a,b); actual!= c{
fmt.Printf("add(%d, %d) = %d; want %d", a, b, actual, c)
}
}
b.ResetTimer() で計測をリセットし、準備に使った時間を測定から外せます。