Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 12185] ファイルの概要

このコミットは、Go言語のテスト実行ツール (test/run.go) に一時的なフラグ show_skips を追加するものです。このフラグの目的は、特定の「レガシーヘッダー」を持つテストファイルを特定しやすくすることにあります。これらのレガシーヘッダーを持つテストはスキップされる傾向があり、このフラグを有効にすることで、通常は表示されないスキップされたテストの結果も出力されるようになります。これは、将来的にこれらのレガシーなテストファイルを新しい形式に変換するための移行作業を支援するための、一時的なデバッグ・可視化機能として導入されました。

コミット

commit a55a5c8df3d8ced8f0399a523dc4508af1db5904
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Fri Feb 24 12:52:15 2012 +1100

    test: add temporary show_skips flag.
    
    To find test files with legacy headers.
    
    We can remove this flag once everything is converted.
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/5694060

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/a55a5c8df3d8ced8f0399a523dc4508af1db5904

元コミット内容

このコミットは、Goのテストスイート実行スクリプトである test/run.go に、show_skips という一時的なコマンドラインフラグを追加します。このフラグは、テストがスキップされた場合にその情報を表示するために使用されます。コミットメッセージによると、この機能は「レガシーヘッダーを持つテストファイルを見つけるため」に導入され、「すべてが変換されたらこのフラグは削除できる」と明記されています。これは、特定の古い形式のテストファイルがテストランナーによってスキップされる動作をしており、それらを特定し、新しい形式に移行するためのデバッグ支援ツールとして機能することを意味します。

変更の背景

Go言語のテストフレームワークは進化しており、過去には異なるテストファイルの記述形式やヘッダーの慣習が存在した可能性があります。このコミットが作成された時点では、おそらく一部のテストファイルが古い形式の「レガシーヘッダー」を使用しており、これが原因でテストランナーがそれらのテストを自動的にスキップする動作をしていたと考えられます。

通常、Goのテストランナーはスキップされたテストの詳細をデフォルトでは表示しません。しかし、これらのレガシーなテストファイルを特定し、新しい標準に準拠するように変換するためには、どのテストがスキップされているのか、そしてなぜスキップされているのかを可視化する必要がありました。

show_skips フラグは、この可視化のニーズに応えるために導入されました。これにより、開発者はスキップされたテストを明確に識別し、それらのファイルを特定して修正作業を進めることができるようになります。コミットメッセージで「一時的」とされているのは、すべてのレガシーテストが変換され、このデバッグ機能が不要になった時点で削除されることを前提としているためです。これは、コードベースのクリーンアップと、一時的なデバッグツールのライフサイクル管理の良い例と言えます。

前提知識の解説

Go言語のテストフレームワーク

Go言語には、標準ライブラリとして testing パッケージが提供されており、これを用いてユニットテストやベンチマークテストを記述します。テストファイルは通常、テスト対象のGoファイルと同じディレクトリに _test.go というサフィックスを付けて配置されます。

go test コマンド

go test コマンドは、Goプロジェクトのテストを実行するための主要なツールです。このコマンドは、指定されたパッケージ内の _test.go ファイルをコンパイルし、テスト関数を実行します。

テストのスキップ (t.Skip())

testing パッケージの *testing.T 型には、Skip() メソッドが用意されています。テスト関数内で t.Skip() を呼び出すと、そのテストはスキップされ、テストランナーはそれ以降のテストコードの実行を停止します。スキップされたテストは、通常、テスト結果のサマリーには「SKIP」として表示されますが、詳細な出力(go test -v)がない限り、その理由や具体的なテスト名は表示されないことがあります。

flag パッケージ

Goの標準ライブラリには、コマンドライン引数を解析するための flag パッケージがあります。これにより、プログラムは -v-n のようなフラグを受け取り、それに応じて動作を変更できます。このコミットでは、flag.Bool を使用して show_skips というブーリアン型のフラグを定義しています。

レガシーヘッダー

この文脈における「レガシーヘッダー」は、Goのテストファイル内で使用されていた、現在では非推奨または互換性のない何らかのメタデータや記述形式を指していると考えられます。具体的な形式はコミットメッセージからは不明ですが、テストランナーがこれらのヘッダーを認識し、関連するテストを自動的にスキップするような内部ロジックが存在したと推測されます。これは、Go言語やそのツールチェインが進化する過程で、古い記述方法が新しいものに置き換えられる際に発生する一般的な状況です。

技術的詳細

このコミットの技術的な変更は、test/run.go ファイルに集中しています。このファイルは、Goのテストスイートを実行するためのカスタムテストランナーとして機能しているようです。

  1. showSkips フラグの追加: flag.Bool("show_skips", false, "show skipped tests") という行が追加され、showSkips という新しいブーリアン型のコマンドラインフラグが定義されました。デフォルト値は false で、通常はスキップされたテストは表示されません。

  2. スキップされたテストの処理ロジックの変更: 既存のテスト結果処理ループ内で、スキップされたテスト (isSkiptrue の場合) の扱いが変更されました。

    • 変更前は、スキップされたテストの場合、resCount["skip"]++ でスキップ数をカウントし、!*verbose (詳細モードでない場合) は continue でループの次のイテレーションに進み、スキップされたテストの出力を抑制していました。
    • 変更後は、まず errStr"skip" に設定します。そして、スキップされたテストが詳細モード (*verbose) でもなく、かつ showSkips フラグも有効でない場合にのみ continue するように条件が変更されました。

    具体的には、以下の条件が追加されました。

    if isSkip && !*verbose && !*showSkips {
        continue
    }
    

    この条件は、「テストがスキップされ、かつ詳細モードではなく、かつ show_skips フラグも有効でない場合」にのみ、そのテストの出力処理をスキップすることを意味します。つまり、show_skips フラグが true であれば、たとえ詳細モードでなくても、スキップされたテストの結果が出力されるようになります。

この変更により、開発者は go run test/run.go -show_skips のようにコマンドを実行することで、通常は隠されているスキップされたテストの情報を強制的に表示させることが可能になります。これは、特定のテストがなぜスキップされているのか、どのファイルが影響を受けているのかをデバッグする際に非常に役立ちます。

コアとなるコードの変更箇所

--- a/test/run.go
+++ b/test/run.go
@@ -32,6 +32,7 @@ var (
 	verbose     = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.")
 	numParallel = flag.Int("n", 8, "number of parallel tests to run")
 	summary     = flag.Bool("summary", false, "show summary of results")
+	showSkips   = flag.Bool("show_skips", false, "show skipped tests")
 )
 
 var (
@@ -98,13 +99,10 @@ func main() {
 	for _, test := range tests {
 		<-test.donec
 		_, isSkip := test.err.(skipError)
+\t\terrStr := "pass"
 		if isSkip {
-\t\t\tresCount["skip"]++
-\t\t\tif !*verbose {\n-\t\t\t\tcontinue
-\t\t\t}\n+\t\t\terrStr = "skip"
 		}
-\t\terrStr := "pass"
 		if test.err != nil {
 			errStr = test.err.Error()
 			if !isSkip {
@@ -112,9 +110,12 @@ func main() {
 			}
 		}
 		resCount[errStr]++
+\t\tif isSkip && !*verbose && !*showSkips {
+\t\t\tcontinue
+\t\t}\n \t\tif !*verbose && test.err == nil {\n \t\t\tcontinue
-\t}\n+\t\t}\n \t\tfmt.Printf("%-10s %-20s: %s\\n", test.action, test.goFileName(), errStr)
 	}\n 

コアとなるコードの解説

test/run.go の変更点

  1. showSkips フラグの定義:

    var (
    	// ... 既存のフラグ定義 ...
    	showSkips   = flag.Bool("show_skips", false, "show skipped tests")
    )
    

    flag.Bool 関数を使って、show_skips という名前のコマンドラインフラグを定義しています。このフラグはブーリアン型で、デフォルト値は false です。説明として「show skipped tests」が与えられています。これにより、test/run.go を実行する際に -show_skips を指定することで、このフラグを true に設定できます。

  2. スキップされたテストの出力ロジックの変更: main 関数内のテスト結果を処理するループにおいて、スキップされたテスト (isSkiptrue) の扱いが変更されています。

    変更前:

    		_, isSkip := test.err.(skipError)
    		if isSkip {
    			resCount["skip"]++
    			if !*verbose {
    				continue
    			}
    		}
    		errStr := "pass" // この行はスキップされたテストのブロックの外にあった
    

    スキップされたテストの場合、resCount["skip"] をインクリメントし、verbose フラグが false の場合は continue して、そのテストの出力を完全にスキップしていました。つまり、詳細モードでない限り、スキップされたテストは表示されませんでした。

    変更後:

    		_, isSkip := test.err.(skipError)
    		errStr := "pass" // errStr の初期化が isSkip のチェックの直後に移動
    		if isSkip {
    			errStr = "skip" // スキップされた場合、errStr を "skip" に設定
    		}
    		// ... (test.err が nil でない場合の処理) ...
    		resCount[errStr]++ // errStr に応じてカウント
    		if isSkip && !*verbose && !*showSkips {
    			continue // スキップされ、詳細モードでもなく、showSkips も有効でない場合のみスキップ
    		}
    		if !*verbose && test.err == nil {
    			continue
    		}
    		fmt.Printf("%-10s %-20s: %s\\n", test.action, test.goFileName(), errStr)
    
    • errStr := "pass" の初期化が isSkip のチェックの直後に移動しました。
    • if isSkip ブロック内で、errStr"skip" に設定されるようになりました。これにより、スキップされたテストも errStr を持つようになります。
    • 最も重要な変更は、continue する条件が if isSkip && !*verbose && !*showSkips となった点です。
      • isSkip: テストがスキップされた場合。
      • !*verbose: 詳細モード (-v) が有効でない場合。
      • !*showSkips: 新しく追加された show_skips フラグが有効でない場合。 この3つの条件がすべて真の場合にのみ、continue が実行され、テストの出力が抑制されます。 つまり、showSkips フラグが true であれば (!*showSkipsfalse になるため)、たとえ verbose フラグが false であっても、スキップされたテストの結果は fmt.Printf によって出力されるようになります。

この変更により、開発者は test/run.go を実行する際に -show_skips フラグを指定することで、通常は非表示となるスキップされたテストの情報を強制的に表示させ、レガシーヘッダーを持つテストファイルの特定と変換作業を効率的に進めることができるようになりました。

関連リンク

このコミットはGo言語の内部テストツールに関するものであり、特定の外部ドキュメントや関連するGoのIssue/Proposalは直接的には見当たりません。しかし、Goのテストに関する一般的な情報源は以下の通りです。

参考にした情報源リンク