自分の関わっているWebサービスは、一部をGo言語で実装している。
今回、testingパッケージを導入して、単体テストの一部を自動化したので、そのメモを残します。
環境
% sw_vers
ProductName: macOS
ProductVersion: 13.5
BuildVersion: 22G74
% go version
go version go1.21.6 darwin/arm64
ソースコード
2つの数値を加算する関数add
をテスト対象として記述したテストコードを例としています。
テスト対象
example/add.go
package example
func add(a, b int) int {
return a + b
}
テストコード
example/add_test.go
package example
import "testing"
func TestAdd(t *testing.T) {
type Args struct {
a int
b int
}
type Wants struct {
c int
}
tests := []struct {
name string
args Args
wants Wants
}{
{"test-ok-1", Args{1, 2}, Wants{3}},
{"test-ok-2", Args{3, -4}, Wants{-1}},
// {"test-ng", Args{-5, 6}, Wants{11}}, <= 失敗例
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := add(tt.args.a, tt.args.b)
if got != tt.wants.c {
t.Errorf("add() = %v, want %v", got, tt.wants.c)
}
})
}
}
テスト実行
実行(オプションなし)
go test テスト対象ディレクトリ
でテストを実行できる。
% go test ./example
ok example.com/testing/example 0.406s
失敗するtest-ng
を有効にして実行した場合、次のように失敗した内容を出力してくれる。
% go test ./example
--- FAIL: TestAdd (0.00s)
--- FAIL: TestAdd/test-ng (0.00s)
add_test.go:26: add() = 1, want 11
FAIL
FAIL example.com/testing/example 0.449s
FAIL
キャッシュ削除
ソースコードの変更がない状態でテストを実行すると、キャッシュされた前回の結果が出力される。
% go test ./example
ok example.com/testing/example (cached)
キャッシュを削除するにはgo clean -testcache
を実行する。
% go test ./example
ok example.com/testing/example (cached)
% go clean -testcache
% go test ./example
ok example.com/testing/example 0.404s
また、-count=1
オプションを指定して実行した場合、キャッシュが残らない。
% go test ./example -count=1
ok example.com/testing/example 0.174s
% go test ./example -count=1
ok example.com/testing/example 0.127s
詳細を出力する
-v
オプションを指定して実行すると、詳細を出力してくれる。
% go test ./example -v
=== RUN TestAdd
=== RUN TestAdd/test-ok-1
=== RUN TestAdd/test-ok-2
--- PASS: TestAdd (0.00s)
--- PASS: TestAdd/test-ok-1 (0.00s)
--- PASS: TestAdd/test-ok-2 (0.00s)
PASS
ok example.com/testing/example 0.392s
失敗するtest-ng
を有効にして実行した場合は、次のように出力される。
% go test ./example -v
=== RUN TestAdd
=== RUN TestAdd/test-ok-1
=== RUN TestAdd/test-ok-2
=== RUN TestAdd/test-ng
add_test.go:26: add() = 1, want 11
--- FAIL: TestAdd (0.00s)
--- PASS: TestAdd/test-ok-1 (0.00s)
--- PASS: TestAdd/test-ok-2 (0.00s)
--- FAIL: TestAdd/test-ng (0.00s)
FAIL
FAIL example.com/testing/example 0.400s
FAIL
あとがき
今回、自動化した対象は、この記事にサンプルとして記述しているadd
のようなユーティリティ的に使われる関数のみだが、標準のモックやhttptest
パッケージもあるようなので、使いこなせれば、ほとんどの単体テストは自動化できそう。
とはいえ、testing
パッケージ自体の理解も足りてないので、まずは、勉強します。