go1.20
は実行時にコードカバレッジを収集する機能を導入しました
以下は簡単な HTTP サービスの例です:
func main() {
var firstVisit atomic.Bool
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if firstVisit.CompareAndSwap(false, true) {
w.Write([]byte("こんにちは、最初の訪問者"))
} else {
w.Write([]byte("こんにちは"))
}
})
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
ディレクトリ内にカバレッジ関連のファイルが表示されます。プログラムが異常終了した場合、例えば panic や 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
ファイルが存在し、同じバイナリファイルを複数回実行しても、1 つの covmeta ファイルのみが出力されます
$ 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 出力が /tmp/cover3154511218/coverage.html に書き込まれました
出力された HTML ファイルを開くと以下のようになります: