[インデックス 1168] ファイルの概要
このコミットは、Go言語の初期のテストフレームワークにおいて、テストの実行状況をより詳細に出力するための -chatty
フラグを追加するものです。具体的には、src/lib/testing.go
ファイルに変更が加えられ、テストの開始時 (=== RUN
) と成功時 (--- PASS
) にメッセージを出力する機能が導入されました。これにより、ユーザーはテストの進行状況をより詳細に把握できるようになります。
コミット
commit 23bd1298f746102b33263617ea3c90239239ab4a
Author: Russ Cox <rsc@golang.org>
Date: Tue Nov 18 17:52:05 2008 -0800
add -chatty flag to test.
was supposed to be in some other cl but got dropped.
R=r
DELTA=21 (16 added, 2 deleted, 3 changed)
OCL=19531
CL=19539
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/23bd1298f746102b33263617ea3c90239239ab4a
元コミット内容
add -chatty flag to test.
was supposed to be in some other cl but got dropped.
R=r
DELTA=21 (16 added, 2 deleted, 3 changed)
OCL=19531
CL=19539
変更の背景
このコミットの背景には、Go言語のテスト実行時の出力に関する改善の意図があります。コミットメッセージにある「was supposed to be in some other cl but got dropped.」という記述から、この -chatty
フラグの追加は元々別の変更リスト(Change List, CL)に含まれる予定だったが、何らかの理由でそのCLからは除外され、改めて独立したコミットとして追加されたことが伺えます。
テストの実行において、通常は失敗したテストのみが報告され、成功したテストについては簡潔なサマリーのみが表示されることが多いです。しかし、大規模なテストスイートや、特定のテストの実行状況を詳細に追跡したい場合、成功したテストも含めて個々のテストの開始と終了、そしてその結果を逐次的に表示する機能が求められることがあります。この -chatty
フラグは、そのような詳細な出力("chatty" = おしゃべりな、多弁な)を有効にするために導入されました。これにより、開発者はテストの進行状況をより細かく把握し、デバッグや問題の特定を容易にすることができます。
前提知識の解説
このコミットを理解するためには、以下のGo言語の基本的な概念と、当時のテストフレームワークの構造に関する知識が必要です。
-
Go言語の
flag
パッケージ: Go言語には、コマンドライン引数を解析するための標準パッケージflag
があります。このパッケージを使用すると、プログラムの実行時に-name value
の形式で引数を渡すことで、プログラムの挙動を動的に変更できます。flag.Bool(name, default_value, *variable, usage)
: ブール型のフラグを定義し、その値を指定された変数にバインドします。flag.Parse()
: コマンドライン引数を実際に解析し、定義されたフラグに対応する変数に値を設定します。この関数は通常、main
関数の冒頭で呼び出されます。
-
Go言語の
init
関数: Go言語には、パッケージがインポートされた際に自動的に実行されるinit
関数という特別な関数があります。各パッケージは複数のinit
関数を持つことができ、これらはパッケージ内のすべての変数の宣言と初期化が完了した後、かつmain
関数が実行される前に、宣言された順序で実行されます。このコミットでは、init
関数内で-chatty
フラグを定義しています。 -
Go言語の初期のテストフレームワーク (
testing
パッケージ): Go言語のテストは、testing
パッケージを使用して記述されます。当時のGoのテストフレームワークは現在とは異なる部分が多く、このコミットに見られるように、Test
構造体やMain
関数といった要素が直接公開されていました。export type Test struct { name string; f *() bool; }
: テストの構造を定義しています。name
はテスト名、f
はテスト関数へのポインタ(当時のGoの関数型は現在と表記が異なる場合があります)です。export func Main(tests *[]Test)
: テストスイートのエントリポイントとなる関数です。この関数が、与えられたテストのリストを順に実行します。
-
println
関数とsys.exit
: 当時のGo言語では、標準出力への出力にはprintln
関数が使われていました。また、プログラムの終了コードを設定するにはsys.exit
が使われていました。これらは現在のfmt
パッケージやos.Exit
に相当する機能です。
技術的詳細
このコミットの技術的な核心は、Go言語の flag
パッケージと testing
パッケージの連携にあります。
-
フラグの定義と初期化:
src/lib/testing.go
の冒頭にimport ("flag")
が追加され、flag
パッケージが利用可能になります。var chatty bool;
でブール型の変数chatty
が宣言されます。この変数が-chatty
フラグの値を保持します。func init() { flag.Bool("chatty", false, &chatty, "chatty"); }
というinit
関数が追加されます。この関数は、testing
パッケージがロードされる際に自動的に実行され、以下の処理を行います。flag.Bool("chatty", false, &chatty, "chatty")
:-chatty
という名前のブール型フラグを定義します。デフォルト値はfalse
で、その値はchatty
変数に格納されます。最後の "chatty" はフラグの利用方法を示す説明文です。
-
コマンドライン引数の解析:
export func Main(tests *[]Test)
関数の冒頭にflag.Parse();
が追加されます。これにより、テストが実行される前にコマンドライン引数が解析され、もし-chatty
フラグが指定されていれば、chatty
変数の値がtrue
に設定されます。 -
テスト出力の制御: テストのループ内で、
chatty
変数の値に基づいて出力が制御されます。if chatty { println("=== RUN ", tests[i].name); }
: テストが実行される直前に、chatty
がtrue
の場合にのみ「=== RUN [テスト名]」というメッセージが出力されます。これにより、どのテストが現在実行されているかが明確になります。if !ok1 { ok = false; println("--- FAIL", tests[i].name); }
: テストが失敗した場合 (ok1
がfalse
) は、chatty
の値に関わらず「--- FAIL [テスト名]」というメッセージが出力されます。これは、失敗したテストは常に報告されるべきであるという原則に基づいています。else if chatty { println("--- PASS", tests[i].name); }
: テストが成功した場合 (ok1
がtrue
) かつchatty
がtrue
の場合にのみ、「--- PASS [テスト名]」というメッセージが出力されます。chatty
がfalse
の場合、成功したテストに関する個別の出力は行われません。
この変更により、ユーザーは -chatty
フラグを付けてテストを実行することで、より詳細なテストの実行ログを得られるようになります。
コアとなるコードの変更箇所
src/lib/testing.go
ファイルにおける変更は以下の通りです。
--- a/src/lib/testing.go
+++ b/src/lib/testing.go
@@ -4,23 +4,37 @@
package testing
+ import (
+ "flag"
+ )
+
+ var chatty bool;
+ func init() {
+ flag.Bool("chatty", false, &chatty, "chatty");
+ }
+
export type Test struct {
name string;
f *() bool;
}
export func Main(tests *[]Test) {
+\tflag.Parse();
ok := true;
for i := 0; i < len(tests); i++ {\
+\t\tif chatty {\
+\t\t\tprintln("=== RUN ", tests[i].name);\
+\t\t}\
ok1 := tests[i].f();
-\t\tstatus := "FAIL";
-\t\tif ok1 {\
-\t\t\tstatus = "PASS"
+\t\tif !ok1 {\
+\t\t\tok = false;\
+\t\t\tprintln("--- FAIL", tests[i].name);\
+\t\t} else if chatty {\
+\t\t\tprintln("--- PASS", tests[i].name);\
}\
-\t\tok = ok && ok1;\
-\t\tprintln(status, tests[i].name);\
}\
if !ok {\
sys.exit(1);\
}\
+\tprintln("PASS");
}
コアとなるコードの解説
-
import ("flag")
の追加: Goの標準ライブラリであるflag
パッケージをインポートしています。これにより、コマンドライン引数を扱う機能が利用可能になります。 -
var chatty bool;
の宣言:chatty
という名前のブール型変数を宣言しています。この変数は、-chatty
コマンドラインフラグが指定されたかどうかを保持します。デフォルトではGoのブール型変数はfalse
に初期化されます。 -
func init() { flag.Bool("chatty", false, &chatty, "chatty"); }
の追加:init
関数は、パッケージがロードされる際に自動的に実行される特別な関数です。この中でflag.Bool
を呼び出すことで、-chatty
という名前のコマンドラインフラグを定義しています。- 最初の
"chatty"
はフラグの名前です。 false
はこのフラグのデフォルト値です。&chatty
は、フラグの値が解析されたときにその値を格納する変数のアドレスです。- 最後の
"chatty"
は、フラグの簡単な説明文です(ヘルプメッセージなどで表示されます)。
- 最初の
-
flag.Parse();
の追加:export func Main(tests *[]Test)
関数の冒頭にflag.Parse()
が追加されました。この関数は、プログラムに渡されたコマンドライン引数を解析し、定義されたフラグ(この場合は-chatty
)の値を対応する変数(chatty
)に設定します。これにより、テスト実行時にユーザーが指定したフラグがプログラムに反映されます。 -
テスト結果出力ロジックの変更: テストのループ内で、テストの実行状況と結果の出力方法が変更されています。
- テスト開始時の出力:
if chatty { println("=== RUN ", tests[i].name); }
chatty
フラグがtrue
の場合のみ、現在実行中のテストの名前の前に「=== RUN 」というプレフィックスを付けて出力します。これにより、テストが開始されたことを明示的に示します。 - テスト失敗時の出力:
if !ok1 { ok = false; println("--- FAIL", tests[i].name); }
テストが失敗した場合 (ok1
がfalse
) は、chatty
フラグの状態に関わらず、常に「--- FAIL [テスト名]」というメッセージを出力します。これは、テストの失敗は常にユーザーに通知されるべき重要な情報であるためです。 - テスト成功時の出力:
else if chatty { println("--- PASS", tests[i].name); }
テストが成功した場合 (ok1
がtrue
) かつchatty
フラグがtrue
の場合にのみ、「--- PASS [テスト名]」というメッセージを出力します。chatty
がfalse
の場合、成功したテストに関する個別の出力は抑制され、より簡潔な出力になります。 - 元の出力の削除:
status := "FAIL"; if ok1 { status = "PASS" } ok = ok && ok1; println(status, tests[i].name);
上記の元の出力ロジックが削除され、新しい条件付き出力に置き換えられました。
- テスト開始時の出力:
-
最終的な「PASS」出力の追加:
println("PASS");
すべてのテストが成功した場合に、最後に「PASS」というメッセージが出力されるようになりました。これは、テストスイート全体の成功を示すものです。
これらの変更により、Goのテストフレームワークは、ユーザーが -chatty
フラグを通じてテスト出力の詳細度を制御できるようになり、より柔軟なテスト実行環境を提供できるようになりました。
関連リンク
- Go言語の
flag
パッケージに関する現在のドキュメント: https://pkg.go.dev/flag - Go言語の
testing
パッケージに関する現在のドキュメント: https://pkg.go.dev/testing
参考にした情報源リンク
- Go言語の公式GitHubリポジトリ: https://github.com/golang/go
- Go言語の初期のコミット履歴 (GitHub): https://github.com/golang/go/commits/master?after=23bd1298f746102b33263617ea3c90239239ab4a+1
- Go言語の
init
関数に関する情報: https://go.dev/doc/effective_go#init - Go言語の
println
関数に関する情報 (古いGoのドキュメントや歴史的資料を参照) - Go言語の
sys.exit
に関する情報 (古いGoのドキュメントや歴史的資料を参照)