[インデックス 14074] ファイルの概要
コミット
commit 46bce2ac277fc4639fb6b6f6c99f91ac6125ced8
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date: Sun Oct 7 23:22:01 2012 +0200
test: convert more tests to rundir/compiledir conventions
Update #4139.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6609051
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/46bce2ac277fc4639fb6b6f6c99f91ac6125ced8
元コミット内容
このコミットは、Go言語のテストスイートにおいて、より多くのテストをrundir
およびcompiledir
という新しいテスト実行規約に変換することを目的としています。これは、Go issue #4139の更新の一環として行われました。具体的には、既存のテストファイル(test/fixedbugs/bug191.go
、test/fixedbugs/bug382.go
、test/fixedbugs/bug424.go
、test/import2.go
、test/import4.go
、test/method4.go
)が、それぞれ対応するディレクトリ構造(例: test/fixedbugs/bug191.dir/
)に移動され、テストの実行方法が変更されています。また、test/run.go
ファイル内のテストスキップリストも更新されています。
変更の背景
Go言語のテストフレームワークは進化を続けており、より堅牢で管理しやすいテスト環境を構築するための改善が常に行われています。このコミットの背景には、Goのテスト実行メカニズムの標準化と効率化があります。
従来のGoテストでは、テストファイルが単一のディレクトリに配置され、テストのコンパイルや実行に必要な補助ファイル(例えば、インポートされるパッケージのソースコードなど)も同じディレクトリに置かれることがありました。しかし、これによりテストの依存関係が不明瞭になったり、テストのセットアップが複雑になったりする問題がありました。特に、複数のファイルから構成されるテストや、特定のディレクトリ構造を必要とするテストの場合、all.bash
やrun.go
といったGoの標準テストスクリプトでは実行が困難なケースがありました。
Go issue #4139は、このようなテストの実行と管理に関する課題に対処するためのものでした。このIssueの目的は、テストの依存関係を明確にし、テストのセットアップを簡素化するために、テストを専用のディレクトリ(*.dir
)に隔離する新しい規約を導入することでした。これにより、テストの実行がより予測可能になり、テストフレームワークによる自動化が容易になります。
このコミットは、そのIssueの解決に向けた具体的なステップであり、既存のテストを新しいrundir
/compiledir
規約に移行することで、テストスイート全体の整合性と保守性を向上させています。
前提知識の解説
このコミットを理解するためには、以下のGo言語のテストに関する概念と規約について知っておく必要があります。
Go言語のテストの基本
Go言語では、テストは_test.go
というサフィックスを持つファイルに記述されます。go test
コマンドは、これらのファイルを自動的に検出し、テストを実行します。Goのテストは、通常、testing
パッケージを利用して記述されます。
rundir
、compiledir
、errorcheckdir
規約
これらはGo言語のテストフレームワークにおける特別な規約であり、特定のテストの実行方法やコンパイル方法を制御するために導入されました。
-
rundir
(Run Directory): この規約は、テストが実行時に特定のディレクトリ構造を必要とする場合に使用されます。テストファイル(通常はmain.go
)と、そのテストが依存する他のファイル(例えば、インポートされるローカルパッケージのソースコードなど)が、testname.dir/
という形式のサブディレクトリに配置されます。 テストファイルの先頭に// rundir
というコメントを記述することで、Goのテストランナーはこの規約に従ってテストを実行します。テストランナーは、testname.dir/
ディレクトリ内でテストをコンパイルし、実行します。これにより、テストの実行環境が隔離され、依存関係が明確になります。 -
compiledir
(Compile Directory): この規約は、テストがコンパイル時に特定のディレクトリ構造を必要とする場合に使用されます。rundir
と同様に、テストファイルと依存ファイルはtestname.dir/
サブディレクトリに配置されます。 テストファイルの先頭に// compiledir
というコメントを記述することで、テストランナーはtestname.dir/
ディレクトリ内でテストをコンパイルします。rundir
と異なり、compiledir
はコンパイルの成功のみを検証し、実行は行わない場合があります。これは、コンパイルエラーを意図的にテストする場合や、実行が不要なテストケースに利用されます。 -
errorcheckdir
(Error Check Directory): この規約は、コンパイルエラーが発生することを期待するテストに使用されます。テストファイルはtestname.dir/
サブディレクトリに配置され、そのファイル内に意図的にコンパイルエラーを引き起こすコードが含まれます。 テストファイルの先頭に// errorcheckdir
というコメントを記述することで、テストランナーはtestname.dir/
ディレクトリ内でテストをコンパイルし、期待されるエラーメッセージが出力されることを検証します。これは、コンパイラの特定のエラー検出機能をテストする際に非常に有用です。
これらの規約が導入される前は、テストの実行方法やコンパイル方法がテストファイル内に直接記述されたり(例: $G $D/bug191.dir/a.go && $G $D/bug191.dir/b.go && $G $D/$F.go && $L $F.$A
)、run.go
スクリプト内で特別な処理が記述されたりしていました。新しい規約は、これらの複雑なセットアップを抽象化し、テストの記述を簡素化することを目的としています。
test/run.go
とall.bash
test/run.go
: Go言語のテストスイートを実行するための主要なスクリプトです。このスクリプトは、Goリポジトリ内の様々なテストファイルを検出し、適切な方法で実行します。rundir
やcompiledir
などのディレクティブを解釈し、それに応じてテストのコンパイルや実行環境をセットアップします。all.bash
: Go言語のビルドとテストを全て実行するためのシェルスクリプトです。通常、Goのソースコードを変更した後に、全てのテストがパスすることを確認するために実行されます。test/run.go
を呼び出してテストスイートを実行します。
このコミットでは、test/run.go
内のskipOkay
マップが更新されています。これは、特定のテストがall.bash
によって直接実行されるのではなく、新しいrundir
/compiledir
規約に従ってtest/run.go
によって処理されるようになったため、従来のスキップリストから削除されたことを意味します。
技術的詳細
このコミットの技術的な詳細を掘り下げると、主に以下の点が挙げられます。
-
テストファイルのディレクトリ構造への移行:
- 従来のテストファイル(例:
test/fixedbugs/bug191.go
)は、そのテストが依存するファイルや、テスト本体のコードを直接含んでいました。 - 新しい規約では、これらのテストは
test/fixedbugs/bug191.dir/
のような専用のディレクトリに移動されます。 - 元のテストファイル(例:
test/fixedbugs/bug191.go
)は、package ignored
という非常にシンプルな内容になり、テストの実行方法を示すディレクティブ(例:// rundircmpout
)のみが残されます。これは、このファイル自体が直接コンパイル・実行されるのではなく、test/run.go
がこのディレクティブを読み取り、bug191.dir/
内のファイルを処理することを示しています。 bug191.dir/
内には、テストの本体となるmain.go
や、テストがインポートするローカルパッケージのファイル(例:a.go
,b.go
)が配置されます。
- 従来のテストファイル(例:
-
テストディレクティブの導入:
- 各テストファイルの先頭に
// rundir
、// compiledir
、または// errorcheckdir
といったコメントが追加されています。これらはGoのテストランナーに対する指示として機能します。 - 例えば、
test/fixedbugs/bug191.go
には// rundircmpout
が追加されています。これはrundir
とcmpout
(出力比較)を組み合わせたディレクティブで、bug191.dir/main.go
を実行し、その出力をbug191.out
と比較することを意味します。 test/fixedbugs/bug382.go
には// compiledir
が追加され、test/fixedbugs/bug424.go
には// rundir
が追加されています。test/import2.go
とtest/import4.go
にはそれぞれ// compiledir
と// errorcheckdir
が追加されています。
- 各テストファイルの先頭に
-
test/run.go
の更新:test/run.go
ファイル内のskipOkay
マップから、移行されたテストファイルが削除されています。これは、これらのテストがもはやall.bash
によって直接スキップされる必要がなく、test/run.go
が新しい規約に従って適切に処理するようになったためです。- 具体的には、
import3.go
,import4.go
,method4.go
,fixedbugs/bug191.go
,fixedbugs/bug382.go
,fixedbugs/bug424.go
などがskipOkay
リストから削除されています。
-
テストの自己完結性:
- 新しい規約により、各テストは自身の実行に必要な全てのファイルを専用のディレクトリ内に持つため、より自己完結的になります。これにより、テストの依存関係が明確になり、テストのセットアップやデバッグが容易になります。
- 例えば、
test/fixedbugs/bug424.dir/main.go
は、lib
パッケージをインポートしていますが、このlib
パッケージもbug424.dir/lib.go
として同じディレクトリ内に存在することが期待されます(このコミットのdiffにはlib.go
の追加は含まれていませんが、規約上はそうあるべきです)。
これらの変更は、Go言語のテストインフラストラクチャをよりモジュール化し、スケーラブルにするための重要なステップです。テストの実行ロジックがテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更は、主に以下のファイル群にわたります。
-
test/fixedbugs/bug191.dir/main.go
の新規作成とtest/fixedbugs/bug191.go
の変更:test/fixedbugs/bug191.dir/main.go
が新規作成され、元のbug191.go
のmain
パッケージのコードが移動されています。このファイルは、ドットインポートのバグをテストするものです。test/fixedbugs/bug191.go
は、// rundircmpout
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/fixedbugs/bug382.dir/prog.go
の新規作成とtest/fixedbugs/bug382.go
の変更:test/fixedbugs/bug382.dir/prog.go
が新規作成され、元のbug382.go
のコードが移動されています。test/fixedbugs/bug382.go
は、// compiledir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/fixedbugs/bug424.dir/main.go
の新規作成とtest/fixedbugs/bug424.go
の変更:test/fixedbugs/bug424.dir/main.go
が新規作成され、元のbug424.go
のコードが移動されています。このテストは、インターフェースを介したメソッド呼び出しが、埋め込みレベルや埋め込み順序に関わらず、ローカルに定義されたメソッドを常に呼び出すことを検証します。test/fixedbugs/bug424.go
は、// rundir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/import2.dir/import2.go
の新規作成とtest/import2.go
の変更:test/import2.dir/import2.go
が新規作成され、元のimport2.go
のコードが移動されています。このファイルは、エクスポートされた変数と関数の様々な宣言をテストします。test/import2.go
は、// compiledir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/import3.go
からtest/import2.dir/import3.go
へのリネームと変更:test/import3.go
がtest/import2.dir/import3.go
へリネームされ、// NOTE: This test is not run by 'run.go' ...
のようなコメントが削除されています。
-
test/import4.dir/empty.go
およびtest/import4.dir/import4.go
の新規作成とtest/import4.go
の変更:test/import4.dir/empty.go
とtest/import4.dir/import4.go
が新規作成され、元のimport4.go
のコードが移動されています。import4.go
は、様々な種類の「インポートされたが使用されていない」エラーがコンパイラによって捕捉されることを検証します。test/import4.go
は、// errorcheckdir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/method4.dir/prog.go
の新規作成とtest/method4.go
の変更:test/method4.dir/prog.go
が新規作成され、元のmethod4.go
のコードが移動されています。このテストは、引数を持つメソッド式をテストします。test/method4.go
は、// rundir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/method4a.go
からtest/method4.dir/method4a.go
へのリネームと変更:test/method4a.go
がtest/method4.dir/method4a.go
へリネームされ、不要なコメントが削除されています。
-
test/run.go
の変更:skipOkay
マップから、上記で移行されたテストファイルのエントリが削除されています。
これらの変更は、テストの実行方法を宣言的にし、テストのセットアップを自動化するためのGoテストフレームワークの進化を示しています。
コアとなるコードの解説
このコミットのコアとなる変更は、Go言語のテストの実行方法を、従来のスクリプトベースの手動実行から、rundir
/compiledir
/errorcheckdir
といったディレクティブに基づく自動化された実行へと移行している点にあります。
例えば、test/fixedbugs/bug191.go
の変更を見てみましょう。
変更前 (test/fixedbugs/bug191.go
):
// $G $D/bug191.dir/a.go && $G $D/bug191.dir/b.go && $G $D/$F.go && $L $F.$A
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
package main
import . "./a"
import . "./b"
var _ T
var _ V
func main() {
}
この変更前のコードでは、テストの実行方法がコメントとして直接記述されています。$G
や$L
といったシェルコマンドが使われており、これはGoコンパイラやリンカを直接呼び出してテストをビルド・実行することを示しています。また、「run.go
やall.bash
では実行されない」という注意書きがあり、手動での実行が必要でした。
変更後 (test/fixedbugs/bug191.go
と test/fixedbugs/bug191.dir/main.go
):
test/fixedbugs/bug191.go
は以下のように変更されました。
// rundircmpout
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests bug with dot imports.
package ignored
そして、元のmain
パッケージのコードはtest/fixedbugs/bug191.dir/main.go
に移動されました。
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import . "./a"
import . "./b"
var _ T
var _ V
func main() {
}
この変更により、test/fixedbugs/bug191.go
はもはや実行可能なGoプログラムではなく、単なるテストランナーへの指示ファイルとなります。// rundircmpout
というディレクティブは、test/run.go
に対して、bug191.dir/
ディレクトリ内のmain.go
をコンパイルして実行し、その出力をbug191.out
ファイルと比較するように指示します。
同様に、test/fixedbugs/bug424.go
の変更も見てみましょう。
変更前 (test/fixedbugs/bug424.go
):
// $G $D/$F.dir/lib.go && $G $D/$F.go && $L $F.$A && ./$A.out
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests that method calls through an interface always
// call the locally defined method localT.m independent
// at which embedding level it is and in which order
// embedding is done.
package main
// ... (main function and other types) ...
変更後 (test/fixedbugs/bug424.go
と test/fixedbugs/bug424.dir/main.go
):
test/fixedbugs/bug424.go
は以下のように変更されました。
// rundir
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests that method calls through an interface always
// call the locally defined method localT.m independent
// at which embedding level it is and in which order
// embedding is done.
package ignored
そして、元のmain
パッケージのコードはtest/fixedbugs/bug424.dir/main.go
に移動されました。
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests that method calls through an interface always
// call the locally defined method localT.m independent
// at which embedding level it is and in which order
// embedding is done.
package main
import "./lib"
import "reflect"
import "fmt"
// ... (localI, localT, myT1, myT2, myT3, main function) ...
ここでも、テストの実行ロジックがtest/fixedbugs/bug424.go
から削除され、// rundir
ディレクティブが追加されています。これにより、test/run.go
がbug424.dir/
内のmain.go
をコンパイルして実行するようになります。
これらの変更は、Goのテストスイートの保守性を大幅に向上させます。テストの実行方法がテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。これにより、テストの記述が簡素化され、テストの依存関係が明確になり、テストフレームワークの柔軟性が向上します。また、all.bash
やrun.go
といった上位のテストスクリプトが、個々のテストの実行詳細を意識することなく、統一された方法でテストを処理できるようになります。
関連リンク
- Go issue #4139: https://github.com/golang/go/issues/4139 (このコミットが更新しているIssue)
- Go CL 6609051: https://golang.org/cl/6609051 (このコミットに対応するGerrit Change-List)
参考にした情報源リンク
- Go言語の公式ドキュメント (testingパッケージ): https://pkg.go.dev/testing
- Go言語のテストに関する議論やドキュメント (GoのIssueトラッカーやメーリングリストのアーカイブ):
- Go issue #4139のコメントスレッド
- Goのテストフレームワークの進化に関するブログ記事や発表資料 (一般的な情報源として)
- Go言語のソースコード (特に
src/cmd/go/test.go
やtest/run.go
): Goのテストランナーの実装を理解するために参照。 - Go言語のテスト規約に関する非公式な情報源 (Stack Overflow, 技術ブログなど):
rundir
,compiledir
,errorcheckdir
に関する具体的な使用例や解説。
[インデックス 14074] ファイルの概要
コミット
commit 46bce2ac277fc4639fb6b6f6c99f91ac6125ced8
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date: Sun Oct 7 23:22:01 2012 +0200
test: convert more tests to rundir/compiledir conventions
Update #4139.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6609051
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/46bce2ac277fc4639fb6b6f6c99f91ac6125ced8
元コミット内容
このコミットは、Go言語のテストスイートにおいて、より多くのテストをrundir
およびcompiledir
という新しいテスト実行規約に変換することを目的としています。これは、Go issue #4139の更新の一環として行われました。具体的には、既存のテストファイル(test/fixedbugs/bug191.go
、test/fixedbugs/bug382.go
、test/fixedbugs/bug424.go
、test/import2.go
、test/import4.go
、test/method4.go
)が、それぞれ対応するディレクトリ構造(例: test/fixedbugs/bug191.dir/
)に移動され、テストの実行方法が変更されています。また、test/run.go
ファイル内のテストスキップリストも更新されています。
変更の背景
Go言語のテストフレームワークは進化を続けており、より堅牢で管理しやすいテスト環境を構築するための改善が常に行われています。このコミットの背景には、Goのテスト実行メカニズムの標準化と効率化があります。
従来のGoテストでは、テストファイルが単一のディレクトリに配置され、テストのコンパイルや実行に必要な補助ファイル(例えば、インポートされるパッケージのソースコードなど)も同じディレクトリに置かれることがありました。しかし、これによりテストの依存関係が不明瞭になったり、テストのセットアップが複雑になったりする問題がありました。特に、複数のファイルから構成されるテストや、特定のディレクトリ構造を必要とするテストの場合、all.bash
やrun.go
といったGoの標準テストスクリプトでは実行が困難なケースがありました。
Go issue #4139は、このようなテストの実行と管理に関する課題に対処するためのものでした。このIssueの目的は、テストの依存関係を明確にし、テストのセットアップを簡素化するために、テストを専用のディレクトリ(*.dir
)に隔離する新しい規約を導入することでした。これにより、テストの実行がより予測可能になり、テストフレームワークによる自動化が容易になります。
このコミットは、そのIssueの解決に向けた具体的なステップであり、既存のテストを新しいrundir
/compiledir
規約に移行することで、テストスイート全体の整合性と保守性を向上させています。
前提知識の解説
このコミットを理解するためには、以下のGo言語のテストに関する概念と規約について知っておく必要があります。
Go言語のテストの基本
Go言語では、テストは_test.go
というサフィックスを持つファイルに記述されます。go test
コマンドは、これらのファイルを自動的に検出し、テストを実行します。Goのテストは、通常、testing
パッケージを利用して記述されます。
rundir
、compiledir
、errorcheckdir
規約
これらはGo言語のテストフレームワークにおける特別な規約であり、特定のテストの実行方法やコンパイル方法を制御するために導入されました。
-
rundir
(Run Directory): この規約は、テストが実行時に特定のディレクトリ構造を必要とする場合に使用されます。テストファイル(通常はmain.go
)と、そのテストが依存する他のファイル(例えば、インポートされるローカルパッケージのソースコードなど)が、testname.dir/
という形式のサブディレクトリに配置されます。 テストファイルの先頭に// rundir
というコメントを記述することで、Goのテストランナーはこの規約に従ってテストを実行します。テストランナーは、testname.dir/
ディレクトリ内でテストをコンパイルし、実行します。これにより、テストの実行環境が隔離され、依存関係が明確になります。 -
compiledir
(Compile Directory): この規約は、テストがコンパイル時に特定のディレクトリ構造を必要とする場合に使用されます。rundir
と同様に、テストファイルと依存ファイルはtestname.dir/
サブディレクトリに配置されます。 テストファイルの先頭に// compiledir
というコメントを記述することで、テストランナーはtestname.dir/
ディレクトリ内でテストをコンパイルします。rundir
と異なり、compiledir
はコンパイルの成功のみを検証し、実行は行わない場合があります。これは、コンパイルエラーを意図的にテストする場合や、実行が不要なテストケースに利用されます。 -
errorcheckdir
(Error Check Directory): この規約は、コンパイルエラーが発生することを期待するテストに使用されます。テストファイルはtestname.dir/
サブディレクトリに配置され、そのファイル内に意図的にコンパイルエラーを引き起こすコードが含まれます。 テストファイルの先頭に// errorcheckdir
というコメントを記述することで、テストランナーはtestname.dir/
ディレクトリ内でテストをコンパイルし、期待されるエラーメッセージが出力されることを検証します。これは、コンパイラの特定のエラー検出機能をテストする際に非常に有用です。
これらの規約が導入される前は、テストの実行方法やコンパイル方法がテストファイル内に直接記述されたり(例: $G $D/bug191.dir/a.go && $G $D/bug191.dir/b.go && $G $D/$F.go && $L $F.$A
)、run.go
スクリプト内で特別な処理が記述されたりしていました。新しい規約は、これらの複雑なセットアップを抽象化し、テストの記述を簡素化することを目的としています。
test/run.go
とall.bash
test/run.go
: Go言語のテストスイートを実行するための主要なスクリプトです。このスクリプトは、Goリポジトリ内の様々なテストファイルを検出し、適切な方法で実行します。rundir
やcompiledir
などのディレクティブを解釈し、それに応じてテストのコンパイルや実行環境をセットアップします。all.bash
: Go言語のビルドとテストを全て実行するためのシェルスクリプトです。通常、Goのソースコードを変更した後に、全てのテストがパスすることを確認するために実行されます。test/run.go
を呼び出してテストスイートを実行します。
このコミットでは、test/run.go
内のskipOkay
マップが更新されています。これは、特定のテストがall.bash
によって直接実行されるのではなく、新しいrundir
/compiledir
規約に従ってtest/run.go
によって処理されるようになったため、従来のスキップリストから削除されたことを意味します。
技術的詳細
このコミットの技術的な詳細を掘り下げると、主に以下の点が挙げられます。
-
テストファイルのディレクトリ構造への移行:
- 従来のテストファイル(例:
test/fixedbugs/bug191.go
)は、そのテストが依存するファイルや、テスト本体のコードを直接含んでいました。 - 新しい規約では、これらのテストは
test/fixedbugs/bug191.dir/
のような専用のディレクトリに移動されます。 - 元のテストファイル(例:
test/fixedbugs/bug191.go
)は、package ignored
という非常にシンプルな内容になり、テストの実行方法を示すディレクティブ(例:// rundircmpout
)のみが残されます。これは、このファイル自体が直接コンパイル・実行されるのではなく、test/run.go
がこのディレクティブを読み取り、bug191.dir/
内のファイルを処理することを示しています。 bug191.dir/
内には、テストの本体となるmain.go
や、テストがインポートするローカルパッケージのファイル(例:a.go
,b.go
)が配置されます。
- 従来のテストファイル(例:
-
テストディレクティブの導入:
- 各テストファイルの先頭に
// rundir
、// compiledir
、または// errorcheckdir
といったコメントが追加されています。これらはGoのテストランナーに対する指示として機能します。 - 例えば、
test/fixedbugs/bug191.go
には// rundircmpout
が追加されています。これはrundir
とcmpout
(出力比較)を組み合わせたディレクティブで、bug191.dir/main.go
を実行し、その出力をbug191.out
と比較することを意味します。 test/fixedbugs/bug382.go
には// compiledir
が追加され、test/fixedbugs/bug424.go
には// rundir
が追加されています。test/import2.go
とtest/import4.go
にはそれぞれ// compiledir
と// errorcheckdir
が追加されています。
- 各テストファイルの先頭に
-
test/run.go
の更新:test/run.go
ファイル内のskipOkay
マップから、移行されたテストファイルが削除されています。これは、これらのテストがもはやall.bash
によって直接スキップされる必要がなく、test/run.go
が新しい規約に従って適切に処理するようになったためです。- 具体的には、
import3.go
,import4.go
,method4.go
,fixedbugs/bug191.go
,fixedbugs/bug382.go
,fixedbugs/bug424.go
などがskipOkay
リストから削除されています。
-
テストの自己完結性:
- 新しい規約により、各テストは自身の実行に必要な全てのファイルを専用のディレクトリ内に持つため、より自己完結的になります。これにより、テストの依存関係が明確になり、テストのセットアップやデバッグが容易になります。
- 例えば、
test/fixedbugs/bug424.dir/main.go
は、lib
パッケージをインポートしていますが、このlib
パッケージもbug424.dir/lib.go
として同じディレクトリ内に存在することが期待されます(このコミットのdiffにはlib.go
の追加は含まれていませんが、規約上はそうあるべきです)。
これらの変更は、Go言語のテストインフラストラクチャをよりモジュール化し、スケーラブルにするための重要なステップです。テストの実行ロジックがテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更は、主に以下のファイル群にわたります。
-
test/fixedbugs/bug191.dir/main.go
の新規作成とtest/fixedbugs/bug191.go
の変更:test/fixedbugs/bug191.dir/main.go
が新規作成され、元のbug191.go
のmain
パッケージのコードが移動されています。このファイルは、ドットインポートのバグをテストするものです。test/fixedbugs/bug191.go
は、// rundircmpout
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/fixedbugs/bug382.dir/prog.go
の新規作成とtest/fixedbugs/bug382.go
の変更:test/fixedbugs/bug382.dir/prog.go
が新規作成され、元のbug382.go
のコードが移動されています。test/fixedbugs/bug382.go
は、// compiledir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/fixedbugs/bug424.dir/main.go
の新規作成とtest/fixedbugs/bug424.go
の変更:test/fixedbugs/bug424.dir/main.go
が新規作成され、元のbug424.go
のコードが移動されています。このテストは、インターフェースを介したメソッド呼び出しが、埋め込みレベルや埋め込み順序に関わらず、ローカルに定義されたメソッドを常に呼び出すことを検証します。test/fixedbugs/bug424.go
は、// rundir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/import2.dir/import2.go
の新規作成とtest/import2.go
の変更:test/import2.dir/import2.go
が新規作成され、元のimport2.go
のコードが移動されています。このファイルは、エクスポートされた変数と関数の様々な宣言をテストします。test/import2.go
は、// compiledir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/import3.go
からtest/import2.dir/import3.go
へのリネームと変更:test/import3.go
がtest/import2.dir/import3.go
へリネームされ、// NOTE: This test is not run by 'run.go' ...
のようなコメントが削除されています。
-
test/import4.dir/empty.go
およびtest/import4.dir/import4.go
の新規作成とtest/import4.go
の変更:test/import4.dir/empty.go
とtest/import4.dir/import4.go
が新規作成され、元のimport4.go
のコードが移動されています。import4.go
は、様々な種類の「インポートされたが使用されていない」エラーがコンパイラによって捕捉されることを検証します。test/import4.go
は、// errorcheckdir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/method4.dir/prog.go
の新規作成とtest/method4.go
の変更:test/method4.dir/prog.go
が新規作成され、元のmethod4.go
のコードが移動されています。このテストは、引数を持つメソッド式をテストします。test/method4.go
は、// rundir
ディレクティブとpackage ignored
のみを含むように変更されています。
-
test/method4a.go
からtest/method4.dir/method4a.go
へのリネームと変更:test/method4a.go
がtest/method4.dir/method4a.go
へリネームされ、不要なコメントが削除されています。
-
test/run.go
の変更:skipOkay
マップから、上記で移行されたテストファイルのエントリが削除されています。
これらの変更は、テストの実行方法を宣言的にし、テストのセットアップを自動化するためのGoテストフレームワークの進化を示しています。
コアとなるコードの解説
このコミットのコアとなる変更は、Go言語のテストの実行方法を、従来のスクリプトベースの手動実行から、rundir
/compiledir
/errorcheckdir
といったディレクティブに基づく自動化された実行へと移行している点にあります。
例えば、test/fixedbugs/bug191.go
の変更を見てみましょう。
変更前 (test/fixedbugs/bug191.go
):
// $G $D/bug191.dir/a.go && $G $D/bug191.dir/b.go && $G $D/$F.go && $L $F.$A
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
package main
import . "./a"
import . "./b"
var _ T
var _ V
func main() {
}
この変更前のコードでは、テストの実行方法がコメントとして直接記述されています。$G
や$L
といったシェルコマンドが使われており、これはGoコンパイラやリンカを直接呼び出してテストをビルド・実行することを示しています。また、「run.go
やall.bash
では実行されない」という注意書きがあり、手動での実行が必要でした。
変更後 (test/fixedbugs/bug191.go
と test/fixedbugs/bug191.dir/main.go
):
test/fixedbugs/bug191.go
は以下のように変更されました。
// rundircmpout
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests bug with dot imports.
package ignored
そして、元のmain
パッケージのコードはtest/fixedbugs/bug191.dir/main.go
に移動されました。
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import . "./a"
import . "./b"
var _ T
var _ V
func main() {
}
この変更により、test/fixedbugs/bug191.go
はもはや実行可能なGoプログラムではなく、単なるテストランナーへの指示ファイルとなります。// rundircmpout
というディレクティブは、test/run.go
に対して、bug191.dir/
ディレクトリ内のmain.go
をコンパイルして実行し、その出力をbug191.out
ファイルと比較するように指示します。
同様に、test/fixedbugs/bug424.go
の変更も見てみましょう。
変更前 (test/fixedbugs/bug424.go
):
// $G $D/$F.dir/lib.go && $G $D/$F.go && $L $F.$A && ./$A.out
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests that method calls through an interface always
// call the locally defined method localT.m independent
// at which embedding level it is and in which order
// embedding is done.
package main
// ... (main function and other types) ...
変更後 (test/fixedbugs/bug424.go
と test/fixedbugs/bug424.dir/main.go
):
test/fixedbugs/bug424.go
は以下のように変更されました。
// rundir
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests that method calls through an interface always
// call the locally defined method localT.m independent
// at which embedding level it is and in which order
// embedding is done.
package ignored
そして、元のmain
パッケージのコードはtest/fixedbugs/bug424.dir/main.go
に移動されました。
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests that method calls through an interface always
// call the locally defined method localT.m independent
// at which embedding level it is and in which order
// embedding is done.
package main
import "./lib"
import "reflect"
import "fmt"
// ... (localI, localT, myT1, myT2, myT3, main function) ...
ここでも、テストの実行ロジックがtest/fixedbugs/bug424.go
から削除され、// rundir
ディレクティブが追加されています。これにより、test/run.go
がbug424.dir/
内のmain.go
をコンパイルして実行するようになります。
これらの変更は、Goのテストスイートの保守性を大幅に向上させます。テストの実行方法がテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。これにより、テストの記述が簡素化され、テストの依存関係が明確になり、テストフレームワークの柔軟性が向上します。また、all.bash
やrun.go
といった上位のテストスクリプトが、個々のテストの実行詳細を意識することなく、統一された方法でテストを処理できるようになります。
関連リンク
- Go issue #4139: https://github.com/golang/go/issues/4139 (このコミットが更新しているIssue)
- Go CL 6609051: https://golang.org/cl/6609051 (このコミットに対応するGerrit Change-List)
参考にした情報源リンク
- Go言語の公式ドキュメント (testingパッケージ): https://pkg.go.dev/testing
- Go言語のテストに関する議論やドキュメント (GoのIssueトラッカーやメーリングリストのアーカイブ):
- Go issue #4139のコメントスレッド
- Goのテストフレームワークの進化に関するブログ記事や発表資料 (一般的な情報源として)
- Go言語のソースコード (特に
src/cmd/go/test.go
やtest/run.go
): Goのテストランナーの実装を理解するために参照。 - Go言語のテスト規約に関する非公式な情報源 (Stack Overflow, 技術ブログなど):
rundir
,compiledir
,errorcheckdir
に関する具体的な使用例や解説。