go1.20
は、実行時にコードカバレッジを収集する機能を導入しました。
Integration tests のためのカバレッジプロファイリングサポート
以下は、シンプルな HTTP サービスの例です:
func main() {
var firstVisit atomic.Bool
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if firstVisit.CompareAndSwap(false, true) {
w.Write([]byte("Hello first visiter"))
} else {
w.Write([]byte("Hello"))
}
})
done := make(chan struct{})
http.HandleFunc("/exit", func(w http.ResponseWriter, r *http.Request) {
close(done)
})
go func() {
if err := http.ListenAndServe(":8000", nil); err != nil {
panic(err)
}
}()
<-done
}
コンパイル時に-cover
オプションを追加します。
$ go build -cover
実行時に、カバレッジ情報の出力ディレクトリを指定するためにGOCOVERDIR
環境変数を追加し、その後は通常のバイナリを実行するだけです。プロセスが正常に終了した後、指定したGOCOVERDIR
ディレクトリにカバレッジ関連のファイルが表示されます。プログラムが正常に終了しない場合、パニックや os.Exit によって終了した場合など、出力されるファイルは不完全な場合があります。
# HTTPサーバーを起動
$ GOCOVERDIR=./coverdata ./demo
# インターフェースをテスト
$ http 127.0.0.1:8000/
$ http 127.0.0.1:8000/exit
# 出力ファイルを表示
$ ls coverdata
covcounters.6fd39c6fc688fc732181f8d31bfc2c1f.7892.1677208447525456700
covmeta.6fd39c6fc688fc732181f8d31bfc2c1f
GOCOVERDIR
ディレクトリには、covcounters
とcovmeta
のファイルが存在します。同じバイナリファイルを複数回実行しても、covmeta ファイルは 1 つしか出力されません。
$ ls coverdata
covcounters.6fd39c6fc688fc732181f8d31bfc2c1f.12377.1677208539436884400
covcounters.6fd39c6fc688fc732181f8d31bfc2c1f.7892.1677208447525456700
covmeta.6fd39c6fc688fc732181f8d31bfc2c1f
次に、go ツールチェーンの新しいcovdata
とcover
ツールを使用して、出力されたカバレッジバイナリファイルを処理します。
$ go tool covdata <mode> -i=<dir1,dir2,...> ...flags...
$ go tool cover {-func,-html}
サンプル#
カバレッジを直接出力する#
covdata
を使用して、コードのテストカバレッジを直接取得し、go test -cover
と同じcoverprofile
を出力します。
$ go tool covdata percent -i=./coverdata -o profile.txt
golab/demo coverage: 83.3% of statements
複数回のテストをマージする#
covdata
を使用して、複数回の実行から出力された covcounters ファイルを結合します。-i
で複数のディレクトリを指定できます。
$ go tool covdata merge -i=./coverdata -o=merged
$ ls merged
covcounters.6fd39c6fc688fc732181f8d31bfc2c1f.0.1677208798216472900
covmeta.6fd39c6fc688fc732181f8d31bfc2c1f
関数 / 行ごとのカバレッジを表示する#
cover
ツールを使用すると、具体的な関数やコードのカバレッジ状況を詳細に確認できます。
# 関数ごとに表示
$ go tool cover -func=profile.txt
golab/demo/main.go:8: main 83.3%
total: (statements) 83.3%
# 行ごとに表示し、htmlファイルを出力
$ go tool cover -html=profile.txt
HTML output written to /tmp/cover3154511218/coverage.html
出力された html ファイルを開くと、次のようになります: