Goでカバレッジを取ってテストされていないコードをハイライトする

go testでカバレッジ取れるのは知ってたんですけど、思ったより簡単にテストのプロファイルまで取れてびっくりしたのでその話。

 

カバレッジを取る

これはまあ知ってると思います。

$ go test -cover

 

テストされていないコードをハイライト

次に、テストで実行されていないコードをハイライトするには、こんな感じにするとできます。

$ go test -coverprofile=coverage.out
$ go tool cover -html=coverage.out

coverprofileオプションは、テストのプロファイルをファイルに書き出すためのオプションで、go tool coverは書き出されたプロファイル情報を可視化するツールです。

htmlオプションにファイルを渡すと、勝手にブラウザが開いて、実行済みのコードの緑に、未実行のコードは赤くハイライトした状態で表示してくれて分かりやすいです。

 

その他の機能

go test と go tool cover は他にも色々オプションがあって、プロファイルを取りたい情報を制御できます。

Rob Pikeがこの辺の話について書いたやつがあったので、詳しくはそっちを読んでください。

The cover story - The Go Blog

 

関数ごとのカバレッジを取る

ブラウザで表示したい場合はhtmlオプションを使用しましたが、funcオプションを使用すれば関数ごとのカバレッジも取得できます。

$ go tool cover -func=coverage.out

 

実行された回数を取る

covermodeオプションを使うことで、実行された回数も取得することができます。

$ go test -covermode=count -coverprofile=coverage.out
$ go tool cover -html=coverage.out

実行されていないコードは赤、実行された回数が多くなるほど暗い緑から明るい緑にグラデーションで表示されるので、視覚的にも分かりやすいです。

ここではcovermodeにcountを指定していますが、covermodeには次の値を指定することができます。

set    : 実行されたかどうかを取得(covermodeを指定しない場合このモードが使われる)
count  : 実行された回数を取得
atomic : 実行された回数をconcurrent safeに取得(ただし遅い)

goroutineを使うプログラムの場合、countだと正しい結果が出なさそうですけど、多くの場合はcountでも正しくカウントできるそうです。

 

まとめ

今までそんなにカバレッジを意識してテストを書くことなかったんですけど、標準で簡単に可視化できるようになると意識できるので良いですね。ただ、カバレッジを上げることばかりに気を取られて、本来テストすべきはずのロジックよりのコーナーケースを網羅することを忘れないようにしないと、カバレッジ高いからって安心してしまうので却って逆効果になるかもしれないけど。

それと、coverprofileで吐かれるファイルはただのテキストでパースも楽なので、なんか色々使えそうですね。

あとgo tool って結構おもしろいツールがたくさんあるっぽいので、どこかで一度全部見ておいた方が良いのかもしれないですね。