やりたいこと
- テストのレポートを取得したい
- テストのカバレッジを取得したい
- gitlabにその結果を反映したい
テストのレポートを取得
最終目的はgitlab上で閲覧することなので、JUnit XML
形式で出力できる必要があります。
そこで今回はgotestsumを使って、テストレポートをXMLで出力します。
gotestsum runs tests using go test --json, prints formatted test output, and a summary of the test run. It is designed to work well for both local development, and for automation like CI.
# gotestsumのインストール
go install gotest.tools/gotestsum@latest
# テストレポートをXMLで出力
gotestsum --junitfile report.xml
これで、XMLファイルが取得できるようになりました。gitlab-ciに組み込むと以下のようになります。
image: golang:1.18
unit test:
stage: test
script:
- go install gotest.tools/gotestsum@latest
- gotestsum --junitfile report.xml
artifacts:
when: always
reports:
junit: report.xml
gitlabでCI/CD
→Pipelines
→該当パイプライン
→Testsタブ
と遷移して確認すると、期待通りのレポートが確認できました。
gitlabのドキュメントでは、go-junit-report
を使った方法も紹介されています。
テストのカバレッジを取得したい
まずは、単にカバレッジを取得したい場合、go test
コマンドを用いて以下のように取得できます。
# パッケージごとにカバレッジを取得する
go test -cover ./...
#=> ? hello [no test files]
#=> ? hello/domain [no test files]
#=> ? hello/infrastructure [no test files]
#=> ok hello/repository coverage: 10.2% of statements
#=> ok hello/service coverage: 82.6% of statements
# カバレッジレポートを出力
go test -coverprofile=cover.txt ./...
# 関数ごとのカバレッジと合計を出力
go tool cover -func=coverage.txt
#=> hello/repository/user.go:51: CreateUser 60.0%
#=> ...(略)
#=> hello/service/user.go:35: CreateUser 100.0%
#=> ...(略)
#=> total: (statements) 52.2%
# カバレッジレポートをHTMLに変換
go tool cover -html=cover.txt -o cover.html
ですが今回も先ほどと同様にXML形式で出力する必要があるので、gocover-coberturaを利用します。
This is a simple helper tool for generating XML output in Cobertura format for CIs like Jenkins and others from go tool cover output.
# gocover-coberturaのインストール
go install github.com/boumenot/gocover-cobertura@latest
# カバレッジレポートをXMLで出力
go test -coverprofile=cover.txt ./...
gocover-cobertura < coverage.txt > coverage.xml
gitlab-ciに組み込むと以下のようになります。
image: golang:1.18
unit test:
stage: test
script:
- go test -coverprofile=cover.txt ./...
- go install github.com/boumenot/gocover-cobertura@latest
- gocover-cobertura < coverage.txt > coverage.xml
artifacts:
when: always
reports:
cobertura: coverage.xml
この設定を行うことで、例えばMRで差分を確認した時に、テストコードがどの部分を網羅しているかが視覚的にわかりやすくなります。詳しくは公式ブログ(.NETですが)をご確認ください。(GitLabでコードカバレッジ)
gitlabにその結果を反映したい
これまで登場してきたymlファイルを統合すると以下のようになります。
image: golang:1.18
unit test:
stage: test
script:
- go install gotest.tools/gotestsum@latest
- gotestsum --junitfile report.xml -- -coverprofile=coverage.txt ./...
- go install github.com/boumenot/gocover-cobertura@latest
- gocover-cobertura < coverage.txt > coverage.xml
artifacts:
when: always
reports:
junit: report.xml
cobertura: coverage.xml
gotestsum
は、--
を使うことで、go test
の引数を指定することができます。
最後にMRやPipelineで総カバレッジ率がわかるようにymlファイルに2行だけ追加します。
image: golang:1.18
unit test:
stage: test
script:
- go install gotest.tools/gotestsum@latest
- gotestsum --junitfile report.xml -- -coverprofile=coverage.txt ./...
- go install github.com/boumenot/gocover-cobertura@latest
- gocover-cobertura < coverage.txt > coverage.xml
- go tool cover -func=coverage.txt # here
coverage: '/total:\s+\(statements\)\s+.+%/' # here
artifacts:
when: always
reports:
junit: report.xml
cobertura: coverage.xml
補足すると、gotestsum
でカバレッジ率は出力されてはいたのですが、それは合計ではなくパッケージごとの小計のみでした。そこで、わざわざgo tool cover
を使って総カバレッジ率を出力するようにしています。
coverage
キーワードは、ジョブ結果出力からカバレッジを取得するためのもので、正規表現を用います。
今回はgo tool cover
の出力に合わせた正規表現を指定していて、total: (statements) 52.2%
のような文にマッチします。
MRやPipelineで期待通りに表示できていることを確認しました。
参考
gotestsum
go-junit-report
gocover-cobertura