[インデックス 16751] ファイルの概要
このコミットは、Go言語のテストカバレッジレポートにおける冗長な出力メッセージを修正するものです。具体的には、go test -cover
コマンド実行時に表示されるカバレッジサマリーから「for pkg」という部分を削除し、より簡潔で重複のない表示にする変更が含まれています。
コミット
commit 56cd47b295e033f39534d80effc45f4abe125bec
Author: Russ Cox <rsc@golang.org>
Date: Fri Jul 12 07:34:16 2013 -0400
cmd/go, testing: remove redundant "for pkg" in coverage message
This is a transcript before this change. I've capitalized the text being removed.
Note that it is always near another line that already says fmt, marked with <<<
$ cd $GOROOT/src/pkg/fmt
$ go test -cover
PASS
coverage FOR FMT: 91.3% of statements
ok fmt 0.040s <<<
$ go test -coverpkg strconv
PASS
coverage FOR FMT: 64.9% of statements in strconv
ok fmt 0.039s <<<
$ go test -cover -c
$ ./fmt.test -test.covermode=set <<<
PASS
coverage FOR FMT: 91.3% of statements
$ go test -coverpkg strconv -c
$ ./fmt.test -test.covermode=set <<<
PASS
coverage FOR FMT: 64.9% of statements in strconv
That the summary printed by 'go test [options] fmt' is unchanged:
$ go test -cover fmt
ok fmt 0.040s coverage: 91.3% of statements
$ go test -coverpkg strconv fmt
ok fmt 0.038s coverage: 64.9% of statements in strconv
R=r
CC=gobot, golang-dev
https://golang.org/cl/10932045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/56cd47b295e033f39534d80effc45f4abe125bec
元コミット内容
このコミットの目的は、go test -cover
コマンドの出力から冗長な「for pkg」という文字列を削除することです。コミットメッセージには、変更前の出力例が示されており、カバレッジのサマリー行に「coverage FOR FMT:」のようにパッケージ名が重複して表示されていることが指摘されています。これは、テスト結果の「ok fmt」行にも既にパッケージ名が含まれているため、不要な情報と判断されました。
変更の背景
Goのテストツールgo test
は、-cover
フラグを使用することでコードカバレッジを測定し、その結果をレポートとして出力します。このレポートには、テスト対象のパッケージ名とカバレッジ率が含まれます。しかし、従来の出力形式では、カバレッジサマリーの行に「coverage for [パッケージ名]:」という形式でパッケージ名が表示され、その直後または近くに表示されるテスト結果の行(例: ok fmt 0.040s
)にも同じパッケージ名が含まれていました。
この重複は、ユーザーにとって視覚的なノイズとなり、出力の簡潔さを損ねていました。Russ Cox氏によるこのコミットは、この冗長性を排除し、より洗練されたユーザーエクスペリエンスを提供することを目的としています。特に、go test -coverpkg
のように複数のパッケージのカバレッジを測定する場合でも、各パッケージのカバレッジ情報がより明確に、かつ重複なく表示されるように改善されています。
前提知識の解説
Go言語のテストとカバレッジ
Go言語には、標準でテストフレームワークが組み込まれており、go test
コマンドを使用してテストを実行します。
go test
: Goパッケージのテストを実行するコマンドです。go test -cover
: コードカバレッジを測定し、その結果を標準出力に表示します。カバレッジとは、テストによって実行されたコードの割合を示す指標です。go test -coverpkg [パッケージリスト]
: 指定したパッケージ群のコードカバレッジを測定します。これにより、テスト対象のパッケージだけでなく、依存するパッケージのカバレッジも確認できます。go test -c
: テストバイナリをコンパイルしますが、実行はしません。-test.covermode=set
: コンパイルされたテストバイナリを実行する際に、カバレッジモードを指定します。
正規表現 (Regular Expression)
正規表現は、文字列のパターンを記述するための強力なツールです。このコミットでは、src/cmd/go/test.go
内で、go test
コマンドの出力からカバレッジ情報を抽出するために正規表現が使用されています。
regexp.MustCompile
: Go言語のregexp
パッケージで、正規表現パターンをコンパイルするために使用されます。コンパイルに失敗するとパニック(実行時エラー)を起こします。FindSubmatch
: コンパイルされた正規表現オブジェクトのメソッドで、入力文字列内でパターンにマッチする最初の部分を見つけ、そのマッチした部分とキャプチャグループ(括弧で囲まれた部分)を返します。
fmt.Printf
Go言語のfmt
パッケージは、フォーマットされたI/O(入出力)を提供します。fmt.Printf
関数は、指定されたフォーマット文字列と引数を使用して、標準出力に文字列を整形して出力します。
%s
: 文字列のプレースホルダー。%.1f%%
: 浮動小数点数のプレースホルダー。.1f
は小数点以下1桁まで表示することを意味し、%%
はリテラルの%
文字を出力します。
技術的詳細
この変更は、主にgo test
コマンドの出力処理とカバレッジレポート生成ロジックの2つの部分に影響を与えます。
-
src/cmd/go/test.go
における正規表現の変更:cmd/go
はgo
コマンドの主要な実装が含まれるディレクトリです。test.go
ファイルは、go test
コマンドのロジック、特にテスト結果のパースと表示に関連する部分を扱います。 変更前は、カバレッジのサマリー行からパーセンテージ部分を抽出するために、coverage for [^ ]+: (.*)\n
という正規表現が使用されていました。これは「coverage for 」というリテラル文字列の後に、スペース以外の文字の並び([^ ]+
、つまりパッケージ名)が続き、コロンとスペース、そして任意の文字の並び((.*)
、これがカバレッジパーセンテージと「of statements」の部分)が続くパターンにマッチします。 変更後は、coverage: (.*)\n
という正規表現に変更されました。これにより、「coverage: 」というリテラル文字列の後に続く任意の文字の並びを抽出するようになります。この変更は、src/pkg/testing/cover.go
での出力形式の変更と同期しています。 -
src/pkg/testing/cover.go
における出力フォーマットの変更:pkg/testing
はGoのテストフレームワークのコア部分を提供します。cover.go
ファイルは、コードカバレッジの測定とレポート生成に関連するロジックを含んでいます。 変更前は、coverReport()
関数内でカバレッジサマリーを出力する際に、fmt.Printf("coverage for %s: %.1f%% of statements%s\n", testedPackage, ...)
というフォーマット文字列を使用していました。ここでtestedPackage
はテスト対象のパッケージ名です。 変更後は、fmt.Printf("coverage: %.1f%% of statements%s\n", ...)
というフォーマット文字列に変更されました。これにより、testedPackage
がフォーマット文字列から削除され、「coverage for [パッケージ名]:」という冗長な部分が取り除かれました。
これらの変更により、go test -cover
の出力はより簡潔になり、パッケージ名はok
行で既に提供されているため、重複が解消されます。
コアとなるコードの変更箇所
src/cmd/go/test.go
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -937,7 +937,7 @@ func coveragePercentage(out []byte) string {
// The string looks like
// test coverage for encoding/binary: 79.9% of statements
// Extract the piece from the percentage to the end of the line.
- re := regexp.MustCompile(`coverage for [^ ]+: (.*)\n`)
+ re := regexp.MustCompile(`coverage: (.*)\n`)
matches := re.FindSubmatch(out)
if matches == nil {
// Probably running "go test -cover" not "go test -cover fmt".
src/pkg/testing/cover.go
--- a/src/pkg/testing/cover.go
+++ b/src/pkg/testing/cover.go
@@ -89,5 +89,5 @@ func coverReport() {
if total == 0 {
total = 1
}
- fmt.Printf("coverage for %s: %.1f%% of statements%s\\n", testedPackage, 100*float64(active)/float64(total), coveredPackage)
+ fmt.Printf("coverage: %.1f%% of statements%s\\n", 100*float64(active)/float64(total), coveredPackage)
}
コアとなるコードの解説
src/cmd/go/test.go
の変更
coveragePercentage
関数は、go test
コマンドの出力バイト列(out []byte
)からカバレッジのパーセンテージ部分を抽出するために使用されます。
変更前は、regexp.MustCompile(
coverage for [^ ]+: (.)\n)
という正規表現で、coverage for
の後に続くパッケージ名とコロン、そしてカバレッジ情報全体をキャプチャしていました。
変更後は、regexp.MustCompile(
coverage: (.)\n)
という正規表現に修正されました。これにより、coverage:
という固定文字列の後に続くカバレッジ情報のみを抽出するようになります。これは、src/pkg/testing/cover.go
での出力形式の変更に合わせて、パースする文字列のパターンを調整したものです。
src/pkg/testing/cover.go
の変更
coverReport
関数は、テスト実行後にカバレッジの最終レポートを標準出力に表示する役割を担っています。
変更前は、fmt.Printf("coverage for %s: %.1f%% of statements%s\\n", testedPackage, ...)
という形式で、testedPackage
(テスト対象のパッケージ名)を埋め込んで「coverage for [パッケージ名]:」というメッセージを出力していました。
変更後は、fmt.Printf("coverage: %.1f%% of statements%s\\n", ...)
という形式に変更されました。これにより、testedPackage
の埋め込みが削除され、単に「coverage:」というメッセージの後にカバレッジのパーセンテージとステートメント数が続くようになりました。この変更が、go test -cover
の出力から冗長な「for pkg」が削除される直接の原因です。
これらの変更は、Goのテストカバレッジレポートの出力形式を簡潔にし、ユーザーエクスペリエンスを向上させるための小さな、しかし効果的な改善です。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/
- Go言語のテストに関するドキュメント: https://go.dev/doc/code#Testing
- Go言語のコードカバレッジに関するドキュメント: https://go.dev/blog/cover
参考にした情報源リンク
- Go言語のコミット履歴: https://github.com/golang/go/commits/master
- このコミットのGo CL (Code Review) ページ: https://golang.org/cl/10932045 (現在はGitHubのコミットページにリダイレクトされる可能性があります)
- Go言語の
regexp
パッケージドキュメント: https://pkg.go.dev/regexp - Go言語の
fmt
パッケージドキュメント: https://pkg.go.dev/fmt