コマンドラインから実行するプログラムを作る際、私はGo言語を使うことが多いです。
当ブログの記事をTwitterに投稿するbotもGo言語で作りました。
今まではテストコードを書いていなかったのですが、仕事で書く機会が増えてきたのでこれを機に勉強していこうと思います。
テストコードとは
私は、あるメソッドを実行したときの結果はこうあるべきというのをコード化したものと認識しています。
例えば、2つの引数を受け取ってその和を返すメソッドがあったとしたら、「1と2を渡したら3が返ってくる」というテストコードになります。
当該メソッドを修正した際に誤って和ではなく差を返すようにしてしまった場合、テストコードが想定している結果と返ってくる結果は違うことになり、ここで誤りに気付くことができます。
Go言語におけるテストコードの書き方
Go言語は標準でテストするための機能が備わっています。
具体的には「testing」パッケージです。
このパッケージをインポートしてテストコードを書いていきます。
ここからは簡単なサンプルで説明します。
いわゆるメインプログラムがこちら。
package main
import "fmt"
func main() {
val1 := 10
val2 := 3
fmt.Printf("%d + %d = %d\n", val1, val2, add(val1, val2))
fmt.Printf("%d - %d = %d\n", val1, val2, sub(val1, val2))
}
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
それに「_test」を付与したものがテストコードになります。
package main
import (
"testing"
)
func TestAdd(t *testing.T) {
t.Log("TestAdd Start")
val1 := 5
val2 := 3
expect := val1 + val2
actual := add(val1, val2)
if expect != actual {
t.Error("Func add test fail")
}
t.Log("TestAdd End")
}
func TestSub(t *testing.T) {
t.Log("TestSub Start")
val1 := 5
val2 := 3
expect := val1 - val2
actual := sub(val1, val2)
if expect != actual {
t.Error("Func sub test fail")
}
t.Log("Testsub End")
}
期待される結果と実際にメソッドを実行した結果を比較して、違っていたらメッセージを表示するというテストコードになります。
テストの実行
テストはプログラムソースのあるディレクトリに移動して「go test」で実行できます。
$ go test -v
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
-vは結果を詳細に表示するオプションです。
go.modがないと怒られた場合には以下のコマンドでgo.modファイルを作成します。
$ go mod init {モジュール名}
モジュール名については、今回は「test」としてみました。
$ go mod init test
go: creating new go.mod: module test
go: to add module requirements and sums:
go mod tidy
カレントディレクトリに「go.mod」というファイルが作られているのを確認したら再度「go test」を実行します。
$ go test -v
=== RUN TestAdd
main_test.go:8: TestAdd Start
main_test.go:20: TestAdd End
--- PASS: TestAdd (0.00s)
=== RUN TestSub
main_test.go:24: TestSub Start
main_test.go:36: Testsub End
--- PASS: TestSub (0.00s)
PASS
ok test 0.002s
全てのテストが問題なく終了すると上記のような表示になります。
例えば、subメソッドを修正した際に引数の順番を間違ってしまったとしましょう。
package main
import "fmt"
func main() {
val1 := 10
val2 := 3
fmt.Printf("%d + %d = %d\n", val1, val2, add(val1, val2))
fmt.Printf("%d - %d = %d\n", val1, val2, sub(val1, val2))
}
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
//return x - y
return y - x
}
この場合のテストの結果は以下のようになります。
$ go test -v
=== RUN TestAdd
main_test.go:8: TestAdd Start
main_test.go:20: TestAdd End
--- PASS: TestAdd (0.00s)
=== RUN TestSub
main_test.go:24: TestSub Start
main_test.go:33: Func sub test fail
main_test.go:36: Testsub End
--- FAIL: TestSub (0.00s)
FAIL
exit status 1
FAIL test 0.002s
subメソッドのテストが失敗しているので間違いに気付くことができます。
まとめ
テストコードを書くのにも時間はかかってしまいますが、一度書いてしまえば以降はコマンド一つでメソッドのテストができるので便利です。
これからはなるべくテストコードを書くようにしようと思いました。
コメント