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

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

このコミットは、Go言語のテストフレームワークであるtestingパッケージのgotestユーティリティに関する改善を導入しています。具体的には、テストが一つも作成されていない場合に警告を表示する機能と、chattyモード(詳細出力モード)時に実行されるテストの総数を表示する機能を追加しています。これにより、開発者はテストの実行状況をより正確に把握できるようになり、意図しないテストの欠落を防ぐことができます。

コミット

commit 572cad871961eed816a4935806ed65c53b1e0d03
Author: Rob Pike <r@golang.org>
Date:   Wed Nov 19 11:50:58 2008 -0800

    gotest, via testing.go, should warn you if you failed to create any tests.
    when chatty, it should tell you how many there are.
    
    R=rsc
    DELTA=5  (5 added, 0 deleted, 0 changed)
    OCL=19590
    CL=19590

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

https://github.com/golang/go/commit/572cad871961eed816a4935806ed65c53b1e0d03

元コミット内容

gotest, via testing.go, should warn you if you failed to create any tests.
when chatty, it should tell you how many there are.

R=rsc
DELTA=5  (5 added, 0 deleted, 0 changed)
OCL=19590
CL=19590

変更の背景

このコミットが行われた2008年11月は、Go言語がまだ一般に公開される前の初期開発段階でした。Go言語の設計思想の一つに「シンプルさと実用性」があり、テストフレームワークもその例外ではありません。初期のtestingパッケージは、現在のものと比較して機能が限定的でした。

この変更の背景には、開発者がテストコードを記述する際に直面する可能性のある以下の課題がありました。

  1. テストの欠落の検知: 開発者がテストファイルを作成したものの、何らかの理由(例えば、テスト関数の命名規則の誤りや、テストの登録忘れなど)でテストが一つも認識されず、実行されない場合がありました。このような状況では、テストが実行されたと誤解し、バグを見逃すリスクがありました。このコミットは、テストが一つも存在しない場合に明示的な警告を出すことで、この問題を解決しようとしています。
  2. テスト実行状況の可視化: 大規模なプロジェクトでは、多数のテストが存在することが一般的です。gotest(現在のgo testコマンドに相当)が実行された際に、実際にいくつのテストが発見され、実行されるのかを事前に知ることは、開発者にとって有用な情報です。特に詳細なログが必要なchattyモードにおいて、この情報はテストの健全性を確認する上で役立ちます。

これらの課題に対処するため、testing.go内のMain関数にロジックが追加され、テストの存在チェックとテスト数の表示が行われるようになりました。これにより、Go言語のテスト体験がより堅牢で情報量の多いものへと改善されました。

前提知識の解説

このコミットを理解するためには、以下のGo言語の基本的な概念とテストに関する知識が必要です。

Go言語のtestingパッケージ

Go言語には、標準ライブラリとしてtestingパッケージが提供されており、これを用いてユニットテストやベンチマークテストを記述します。

  • テストファイルの命名規則: Goでは、テストファイルは通常、テスト対象のソースファイルと同じディレクトリに配置され、ファイル名の末尾に_test.goを付けます(例: my_package.goに対するmy_package_test.go)。
  • テスト関数の命名規則: テスト関数はTestで始まり、その後に続く名前が大文字で始まる必要があります(例: func TestMyFunction(t *testing.T))。
  • go testコマンド: Goのテストは、go testコマンドを実行することで自動的に発見され、実行されます。このコマンドは、指定されたパッケージ内の_test.goファイルを探し、その中のテスト関数を実行します。

Test構造体とMain関数

コミットで変更されているsrc/lib/testing.goは、Go言語のtestingパッケージのコア部分を構成しています。

  • export type Test struct { ... }: これは、個々のテストを表す構造体です。通常、テストの名前(nameフィールド)や、テストを実行するための関数ポインタなどが含まれます。
  • export func Main(tests *[]Test): このMain関数は、go testコマンドによってテストが実行される際に呼び出されるエントリポイントのようなものです。tests引数には、発見されたすべてのテストのリストが渡されます。この関数は、リスト内の各テストをループで処理し、実行します。

flagパッケージとflag.Parse()

Go言語の標準ライブラリには、コマンドライン引数を解析するためのflagパッケージがあります。

  • flag.Parse(): この関数は、コマンドラインで指定されたフラグ(オプション)を解析し、対応する変数に値を設定します。go testコマンドも内部的にflagパッケージを使用して、-v(詳細出力)や-run(特定のテストの実行)などのオプションを処理します。

println関数

printlnはGo言語の組み込み関数の一つで、引数を標準出力に出力します。これはデバッグやシンプルなメッセージ表示によく使われます。fmtパッケージのfmt.Printlnと似ていますが、より低レベルで、フォーマット指定ができません。

chatty変数

コミットの変更内容から推測すると、chattyはおそらくtesting.go内で定義されているブール型の変数で、go test -vのように詳細出力モードが有効になっているかどうかを示すフラグです。この変数がtrueの場合、より多くの情報がコンソールに出力されます。

技術的詳細

このコミットは、src/lib/testing.goファイルのMain関数にロジックを追加することで、テスト実行時のユーザーエクスペリエンスを向上させています。

Main関数は、go testコマンドがテストを実行する際に、発見されたすべてのテストのリスト(tests *[]Test)を受け取ります。変更前のMain関数は、このリストを単純にループして各テストを実行していました。

今回の変更では、テストの実行ループに入る前に、以下の2つの条件チェックが追加されました。

  1. if len(tests) == 0:

    • この条件は、testsスライス(Goにおける動的配列)の長さが0であるかどうかをチェックします。
    • len(tests)が0ということは、go testがテストファイル内で一つもテスト関数を発見できなかったことを意味します。
    • この場合、println("warning: no tests available")という警告メッセージが標準出力に表示されます。これにより、開発者はテストが意図せずスキップされたことに気づくことができます。
  2. else if chatty:

    • この条件は、testsスライスにテストが存在し(len(tests) > 0)、かつchatty変数がtrueである場合に評価されます。
    • chattytrueであるということは、ユーザーがgo test -vのような詳細出力オプションを指定していることを示唆します。
    • この場合、println(len(tests), "tests to run")というメッセージが標準出力に表示されます。これにより、実行されるテストの総数が明示され、開発者はテストの規模や実行状況を把握しやすくなります。

これらの変更は、Go言語のテストフレームワークが、よりユーザーフレンドリーで情報量の多いツールへと進化していく初期段階を示しています。特に、テストが発見されないというサイレントな失敗を防ぐための警告は、開発プロセスにおける重要な改善点です。

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

変更はsrc/lib/testing.goファイルに集中しており、以下の5行が追加されています。

--- a/src/lib/testing.go
+++ b/src/lib/testing.go
@@ -21,6 +21,11 @@ export type Test struct {
 export func Main(tests *[]Test) {
 	flag.Parse();
 	ok := true;
+	if len(tests) == 0 {
+		println("warning: no tests available");
+	} else if chatty {
+		println(len(tests), "tests to run");
+	}
 	for i := 0; i < len(tests); i++ {
 		if chatty {
 			println("=== RUN ", tests[i].name);

コアとなるコードの解説

追加されたコードブロックは、Main関数の冒頭、flag.Parse()の呼び出しとテスト実行ループの間に挿入されています。

	if len(tests) == 0 {
		println("warning: no tests available");
	} else if chatty {
		println(len(tests), "tests to run");
	}
  1. if len(tests) == 0 { ... }:

    • testsは、Main関数に渡されるTest構造体のスライスへのポインタです。len(tests)は、このスライスに含まれる要素(つまり、発見されたテストの数)を返します。
    • この条件は、「もし発見されたテストが一つもなければ」という意味になります。
    • この条件が真の場合、println("warning: no tests available");が実行され、コンソールに「warning: no tests available」という警告メッセージが出力されます。これは、開発者がテストを記述したにもかかわらず、go testがそれらを認識できなかった場合に、その状況を明確に伝えるためのものです。
  2. else if chatty { ... }:

    • このelse ifブロックは、len(tests) == 0の条件が偽(つまり、テストが一つ以上発見された場合)のときに評価されます。
    • chattyは、おそらくtesting.go内で定義されているグローバルなブール変数で、go test -vオプションが指定された場合にtrueになるものです。
    • この条件が真の場合(テストがあり、かつ詳細出力モードが有効な場合)、println(len(tests), "tests to run");が実行されます。
    • これにより、例えば5 tests to runのように、実行されるテストの総数がコンソールに出力されます。これは、特に多数のテストがある場合に、テストの実行が開始される前にその数を把握できるため、開発者にとって有用な情報となります。

この変更により、go testの出力がより情報豊富になり、テストの欠落という潜在的な問題を早期に発見できるようになりました。これは、Go言語のテストフレームワークの堅牢性と使いやすさを向上させるための、小さなしかし重要な一歩です。

関連リンク

参考にした情報源リンク

  • Go言語公式ドキュメント
  • Go言語のソースコード (特にsrc/testing/testing.goの現在の実装と比較)
  • Gitのコミット履歴と差分表示
  • Go言語の初期開発に関する一般的な知識
  • Rob Pike氏のGo言語に関する講演や記事 (一般的な背景知識として)
  • go testコマンドの動作に関する情報```markdown

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

このコミットは、Go言語のテストフレームワークであるtestingパッケージのgotestユーティリティに関する改善を導入しています。具体的には、テストが一つも作成されていない場合に警告を表示する機能と、chattyモード(詳細出力モード)時に実行されるテストの総数を表示する機能を追加しています。これにより、開発者はテストの実行状況をより正確に把握できるようになり、意図しないテストの欠落を防ぐことができます。

コミット

commit 572cad871961eed816a4935806ed65c53b1e0d03
Author: Rob Pike <r@golang.org>
Date:   Wed Nov 19 11:50:58 2008 -0800

    gotest, via testing.go, should warn you if you failed to create any tests.
    when chatty, it should tell you how many there are.
    
    R=rsc
    DELTA=5  (5 added, 0 deleted, 0 changed)
    OCL=19590
    CL=19590

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

https://github.com/golang/go/commit/572cad871961eed816a4935806ed65c53b1e0d03

元コミット内容

gotest, via testing.go, should warn you if you failed to create any tests.
when chatty, it should tell you how many there are.

R=rsc
DELTA=5  (5 added, 0 deleted, 0 changed)
OCL=19590
CL=19590

変更の背景

このコミットが行われた2008年11月は、Go言語がまだ一般に公開される前の初期開発段階でした。Go言語の設計思想の一つに「シンプルさと実用性」があり、テストフレームワークもその例外ではありません。初期のtestingパッケージは、現在のものと比較して機能が限定的でした。

この変更の背景には、開発者がテストコードを記述する際に直面する可能性のある以下の課題がありました。

  1. テストの欠落の検知: 開発者がテストファイルを作成したものの、何らかの理由(例えば、テスト関数の命名規則の誤りや、テストの登録忘れなど)でテストが一つも認識されず、実行されない場合がありました。このような状況では、テストが実行されたと誤解し、バグを見逃すリスクがありました。このコミットは、テストが一つも存在しない場合に明示的な警告を出すことで、この問題を解決しようとしています。
  2. テスト実行状況の可視化: 大規模なプロジェクトでは、多数のテストが存在することが一般的です。gotest(現在のgo testコマンドに相当)が実行された際に、実際にいくつのテストが発見され、実行されるのかを事前に知ることは、開発者にとって有用な情報です。特に詳細なログが必要なchattyモードにおいて、この情報はテストの健全性を確認する上で役立ちます。

これらの課題に対処するため、testing.go内のMain関数にロジックが追加され、テストの存在チェックとテスト数の表示が行われるようになりました。これにより、Go言語のテスト体験がより堅牢で情報量の多いものへと改善されました。

前提知識の解説

このコミットを理解するためには、以下のGo言語の基本的な概念とテストに関する知識が必要です。

Go言語のtestingパッケージ

Go言語には、標準ライブラリとしてtestingパッケージが提供されており、これを用いてユニットテストやベンチマークテストを記述します。

  • テストファイルの命名規則: Goでは、テストファイルは通常、テスト対象のソースファイルと同じディレクトリに配置され、ファイル名の末尾に_test.goを付けます(例: my_package.goに対するmy_package_test.go)。
  • テスト関数の命名規則: テスト関数はTestで始まり、その後に続く名前が大文字で始まる必要があります(例: func TestMyFunction(t *testing.T))。
  • go testコマンド: Goのテストは、go testコマンドを実行することで自動的に発見され、実行されます。このコマンドは、指定されたパッケージ内の_test.goファイルを探し、その中のテスト関数を実行します。

Test構造体とMain関数

コミットで変更されているsrc/lib/testing.goは、Go言語のtestingパッケージのコア部分を構成しています。

  • export type Test struct { ... }: これは、個々のテストを表す構造体です。通常、テストの名前(nameフィールド)や、テストを実行するための関数ポインタなどが含まれます。
  • export func Main(tests *[]Test): このMain関数は、go testコマンドによってテストが実行される際に呼び出されるエントリポイントのようなものです。tests引数には、発見されたすべてのテストのリストが渡されます。この関数は、リスト内の各テストをループで処理し、実行します。

flagパッケージとflag.Parse()

Go言語の標準ライブラリには、コマンドライン引数を解析するためのflagパッケージがあります。

  • flag.Parse(): この関数は、コマンドラインで指定されたフラグ(オプション)を解析し、対応する変数に値を設定します。go testコマンドも内部的にflagパッケージを使用して、-v(詳細出力)や-run(特定のテストの実行)などのオプションを処理します。

println関数

printlnはGo言語の組み込み関数の一つで、引数を標準出力に出力します。これはデバッグやシンプルなメッセージ表示によく使われます。fmtパッケージのfmt.Printlnと似ていますが、より低レベルで、フォーマット指定ができません。

chatty変数

コミットの変更内容から推測すると、chattyはおそらくtesting.go内で定義されているブール型の変数で、go test -vのように詳細出力モードが有効になっているかどうかを示すフラグです。この変数がtrueの場合、より多くの情報がコンソールに出力されます。

技術的詳細

このコミットは、src/lib/testing.goファイルのMain関数にロジックを追加することで、テスト実行時のユーザーエクスペリエンスを向上させています。

Main関数は、go testコマンドがテストを実行する際に、発見されたすべてのテストのリスト(tests *[]Test)を受け取ります。変更前のMain関数は、このリストを単純にループして各テストを実行していました。

今回の変更では、テストの実行ループに入る前に、以下の2つの条件チェックが追加されました。

  1. if len(tests) == 0:

    • この条件は、testsスライス(Goにおける動的配列)の長さが0であるかどうかをチェックします。
    • len(tests)が0ということは、go testがテストファイル内で一つもテスト関数を発見できなかったことを意味します。
    • この場合、println("warning: no tests available")という警告メッセージが標準出力に表示されます。これにより、開発者はテストが意図せずスキップされたことに気づくことができます。
  2. else if chatty:

    • この条件は、testsスライスにテストが存在し(len(tests) > 0)、かつchatty変数がtrueである場合に評価されます。
    • chattytrueであるということは、ユーザーがgo test -vのような詳細出力オプションを指定していることを示唆します。
    • この場合、println(len(tests), "tests to run")というメッセージが標準出力に表示されます。これにより、実行されるテストの総数が明示され、開発者はテストの規模や実行状況を把握しやすくなります。

これらの変更は、Go言語のテストフレームワークが、よりユーザーフレンドリーで情報量の多いツールへと進化していく初期段階を示しています。特に、テストが発見されないというサイレントな失敗を防ぐための警告は、開発プロセスにおける重要な改善点です。

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

変更はsrc/lib/testing.goファイルに集中しており、以下の5行が追加されています。

--- a/src/lib/testing.go
+++ b/src/lib/testing.go
@@ -21,6 +21,11 @@ export type Test struct {
 export func Main(tests *[]Test) {
 	flag.Parse();
 	ok := true;
+	if len(tests) == 0 {
+		println("warning: no tests available");
+	} else if chatty {
+		println(len(tests), "tests to run");
+	}
 	for i := 0; i < len(tests); i++ {
 		if chatty {
 			println("=== RUN ", tests[i].name);

コアとなるコードの解説

追加されたコードブロックは、Main関数の冒頭、flag.Parse()の呼び出しとテスト実行ループの間に挿入されています。

	if len(tests) == 0 {
		println("warning: no tests available");
	} else if chatty {
		println(len(tests), "tests to run");
	}
  1. if len(tests) == 0 { ... }:

    • testsは、Main関数に渡されるTest構造体のスライスへのポインタです。len(tests)は、このスライスに含まれる要素(つまり、発見されたテストの数)を返します。
    • この条件は、「もし発見されたテストが一つもなければ」という意味になります。
    • この条件が真の場合、println("warning: no tests available");が実行され、コンソールに「warning: no tests available」という警告メッセージが出力されます。これは、開発者がテストを記述したにもかかわらず、go testがそれらを認識できなかった場合に、その状況を明確に伝えるためのものです。
  2. else if chatty { ... }:

    • このelse ifブロックは、len(tests) == 0の条件が偽(つまり、テストが一つ以上発見された場合)のときに評価されます。
    • chattyは、おそらくtesting.go内で定義されているグローバルなブール変数で、go test -vオプションが指定された場合にtrueになるものです。
    • この条件が真の場合(テストがあり、かつ詳細出力モードが有効な場合)、println(len(tests), "tests to run");が実行されます。
    • これにより、例えば5 tests to runのように、実行されるテストの総数がコンソールに出力されます。これは、特に多数のテストがある場合に、テストの実行が開始される前にその数を把握できるため、開発者にとって有用な情報となります。

この変更により、go testの出力がより情報豊富になり、テストの欠落という潜在的な問題を早期に発見できるようになりました。これは、Go言語のテストフレームワークの堅牢性と使いやすさを向上させるための、小さなしかし重要な一歩です。

関連リンク

参考にした情報源リンク

  • Go言語公式ドキュメント
  • Go言語のソースコード (特にsrc/testing/testing.goの現在の実装と比較)
  • Gitのコミット履歴と差分表示
  • Go言語の初期開発に関する一般的な知識
  • Rob Pike氏のGo言語に関する講演や記事 (一般的な背景知識として)
  • go testコマンドの動作に関する情報