この記事はtomowarkar ひとりAdvent Calendar 2019の3日目の記事です。
今日はgo testを理解していきます。
今回実装する関数
整数配列から最小値を求める関数をそれぞれ実装していきます。
pythonでいうmin
関数ですね。
$ python
>>> min([1,2,3])
1
testingパッケージについて
- Goでのテストはtestingパッケージを使う。
- テストは
{filename}_test.go
というファイルで作成。 - テストのメソッドは命名則があるので注意(以下引用)。
func TestXxx(* testing.T)
ここで、Xxxは小文字で始まっていません。関数名は、テストルーチンを識別するのに役立ちます。
Package testing
テストファイルを同時に作成する
テストを書く場合は同時に作成してしまうと楽そうです。
$ touch math{,_test}.go
$ ls
math.go math_test.go
テストを書く
それでは上記で作成したmathファイル
にコードを書いていきます。TDD的にまずはテストから。
- テーブルを使ってテストを実装
-
min
関数はminInt
として実装 - サブテスト を使ってテストケース毎にテストを分類
package math
import (
"testing"
)
func TestMinInt(t *testing.T) {
tests := []struct {
name string
in []int
want int
}{
{"natural_number_slice", []int{1, 2, 3}, 1},
{"nega_posi", []int{-1, 0}, -1},
{"nega_nega", []int{-10, -11}, -11},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := minInt(tt.in)
if got != tt.want {
t.Fatalf("want %v but %v", tt.want, got)
}
})
}
}
package math
func minInt(slice []int) int {
var min int
return min
}
失敗することを確認
まだminIntを実装しておらずただ0を返すだけの関数なので、テストは当然落ちます。
$ go test
--- FAIL: TestMinInt (0.00s)
--- FAIL: TestMinInt/natural_number_slice (0.00s)
math_test.go:21: want 1 but 0
--- FAIL: TestMinInt/nega_posi (0.00s)
math_test.go:21: want -1 but 0
--- FAIL: TestMinInt/nega_nega (0.00s)
math_test.go:21: want -11 but 0
FAIL
exit status 1
FAIL math 0.006s
一つ目のテスト結果をみてみます
--- FAIL: TestMinInt/natural_number_slice (0.00s)
math_test.go:21: want 1 but 0
データオブジェクトは{"natural_number_slice", []int{1, 2, 3}, 1}
で、テストログのwant 1 but 0
より1が期待されたけれども、得られたのは0ですよといことがわかる。
関数を実装する
テストが落ちることが確認できたので関数を実装します。簡単ですね。
package math
func minInt(slice []int) int {
var min int = slice[0]
for _, value := range slice {
if min > value {
min = value
}
}
return min
}
成功することを確認する
関数を実装したので期待通りに動作することを確認します。
$ go test
PASS
ok math 0.005s
テストの途中経過を確認する
PASSと出ているだけではどのテストを確認したのかわからないため、テストの途中経過を確認したくなりました。
そのような場合は-v
オプションを追加します。
TestMinIntの3つのサブテストを確認した結果PASSになっているのが分かります。
$ go test -v
=== RUN TestMinInt
=== RUN TestMinInt/natural_number_slice
=== RUN TestMinInt/nega_posi
=== RUN TestMinInt/nega_nega
--- PASS: TestMinInt (0.00s)
--- PASS: TestMinInt/natural_number_slice (0.00s)
--- PASS: TestMinInt/nega_posi (0.00s)
--- PASS: TestMinInt/nega_nega (0.00s)
PASS
ok math 0.006s
各関数, サブテスト毎にテスト結果を確認する
今回はTestMinIntしかテスト対象がないため必要としませんが、-run {your_test_method}
オプションで各メソッド毎にテスト結果を確認することができます。
$ go test -run TestMinInt
また同様にして-run {your_test_method/sub_test}
オプションを使ってサブテスト毎にテスト結果を確認することもできます。
$ go test -v -run TestMinInt/natural_number_slic
=== RUN TestMinInt
=== RUN TestMinInt/natural_number_slice
--- PASS: TestMinInt (0.00s)
--- PASS: TestMinInt/natural_number_slice (0.00s)
PASS
ok math 0.005s
テストカバレッジを確認する
最後に-cover
オプションを使ってテストカバレッジを確認します。
$ go test -cover
PASS
coverage: 100.0% of statements
ok math 0.005s
参考記事
まとめ
- go testの書き方がわかった
- go testの各オプションの理解ができた
- テストカバレッジ上げていこう
以上明日も頑張ります!!
tomowarkar ひとりAdvent Calendar Advent Calendar 2019