Go言語でテストのカバレッジを計測する
Go1.2からテストカバレッジの計測がサポートされています。
http://golang.org/doc/go1.2#cover
私が公開しているgo-pop3パッケージを使ってテストカバレッジを計測してみたいと思います。
ソースコードは以下に配置されているものとします。
GOPATH/src/github.com/taknb2nch/go-pop3/
まずはテストが通ることを確認します。
$ go test PASS ok github.com/taknb2nch/go-pop3 0.113s
では次にカバレッジを計測してみます。
$ go test -cover go tool: no such tool "cover"; to install: go get code.google.com/p/go.tools/cmd/cover
さすがWindowsです、coverツール(コマンド)が標準ではインストールされていないようです。
(ちなみにUbuntu上に用意した環境には最初から入っていました)
go get コマンドでcoverをインストールして、再度実行します。
$ go get code.google.com/p/go.tools/cmd/cover $ go test -cover PASS coverage: 68.4% of statements ok github.com/taknb2nch/go-pop3 0.123s
68.4%カバーできているということのようです。
今後は-coverprofileオプションを指定してテストを実行します。
このオプションは-coverで実行し、結果を指定したファイルに出力してくれるようです。ただ出力されたファイルの中身はよくわかりません。
$ go test -coverprofile=coverage.out PASS coverage: 68.4% of statements ok github.com/taknb2nch/go-pop3 0.116s
出力結果は同じですが、同じディレクトリにcoverage.outファイルが作成されています。
次にgo tool coverコマンドで-funcオプションに先程出力されたcoverage.outを指定し実行します。
$ go tool cover -func=coverage.out github.com\taknb2nch\go-pop3\pop3.go: Dial 0.0% github.com\taknb2nch\go-pop3\pop3.go: NewClient 80.0% github.com\taknb2nch\go-pop3\pop3.go: User 100.0% github.com\taknb2nch\go-pop3\pop3.go: Pass 100.0% github.com\taknb2nch\go-pop3\pop3.go: Stat 100.0% github.com\taknb2nch\go-pop3\pop3.go: Retr 75.0% github.com\taknb2nch\go-pop3\pop3.go: List 100.0% github.com\taknb2nch\go-pop3\pop3.go: ListAll 80.0% github.com\taknb2nch\go-pop3\pop3.go: Uidl 78.6% github.com\taknb2nch\go-pop3\pop3.go: UidlAll 80.0% github.com\taknb2nch\go-pop3\pop3.go: Dele 100.0% github.com\taknb2nch\go-pop3\pop3.go: Noop 100.0% github.com\taknb2nch\go-pop3\pop3.go: Rset 100.0% github.com\taknb2nch\go-pop3\pop3.go: Quit 100.0% github.com\taknb2nch\go-pop3\pop3.go: ReceiveMail 0.0% github.com\taknb2nch\go-pop3\pop3.go: cmdSimple 75.0% github.com\taknb2nch\go-pop3\pop3.go: cmdStatOrList 76.5% github.com\taknb2nch\go-pop3\pop3.go: cmdReadLines 75.0% github.com\taknb2nch\go-pop3\pop3.go: Close 100.0% github.com\taknb2nch\go-pop3\pop3.go: convertNumberAndSize 72.7% github.com\taknb2nch\go-pop3\pop3.go: convertNumberAndUid 75.0% github.com\taknb2nch\go-pop3\pop3proto.go: Error 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: NewConn 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: Close 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: NewReader 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: ReadLine 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: ReadLines 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: ReadToPeriod 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: ReadResponse 75.0% github.com\taknb2nch\go-pop3\pop3proto.go: parseResponse 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: NewWriter 100.0% github.com\taknb2nch\go-pop3\pop3proto.go: WriteLine 66.7% total: (statements) 68.4%
するとテスト対象の関数、メソッドごとにガバレッジが表示されます。Dial、ReceiveMail、WriteLineが低いので全体も低くなっているようです。
この結果を視覚化することもできます。先程と同じように今度は-htmlオプションに先程出力されたcoverage.outを指定し実行します。
$ go tool cover -html=coverage.out
すると、ブラウザが起動し以下のような画面が表示されます。
緑色の部分はテストが書けている部分、赤の部分はそうでない部分になります。この画面を見ればどのようなパターンのテストが書けていないかわかります。
また、ステートメントが実行されたかどうかだけでなく、何回実行されたかも計測できます。
回数も計測する場合にはgo testコマンドに-covermove=countを追加して実行します。
$ go test -coverprofile=count.out -covermode=count PASS coverage: 68.4% of statements ok github.com/taknb2nch/go-pop3 0.116s
出力結果は以下のように表示されます。
$ go tool cover -html=count.out
マウスを左端に持って行くと回数がポップアップで表示されます。
ただこれの何が嬉しいのかはまだピンときません。
まとめ
Go言語ではテストカバレッジの計測がサポートされていて、簡単に計測、視覚化することができ、テストの精度を上げることができそうです。
ただ、あくまで実装した関数、メソッドの内容に対して、どれだけテストがカバーできているかを表しているだけなので、そもそも関数やメソッドが仕様を満たしているかを発見することはできません。そのためには仕様を網羅できるテストを書かなくてはならないと思います。そうするためにはTDDがどうこうという話になってくるので、ここでは触れません。