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

[インデックス 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.gotest/fixedbugs/bug382.gotest/fixedbugs/bug424.gotest/import2.gotest/import4.gotest/method4.go)が、それぞれ対応するディレクトリ構造(例: test/fixedbugs/bug191.dir/)に移動され、テストの実行方法が変更されています。また、test/run.goファイル内のテストスキップリストも更新されています。

変更の背景

Go言語のテストフレームワークは進化を続けており、より堅牢で管理しやすいテスト環境を構築するための改善が常に行われています。このコミットの背景には、Goのテスト実行メカニズムの標準化と効率化があります。

従来のGoテストでは、テストファイルが単一のディレクトリに配置され、テストのコンパイルや実行に必要な補助ファイル(例えば、インポートされるパッケージのソースコードなど)も同じディレクトリに置かれることがありました。しかし、これによりテストの依存関係が不明瞭になったり、テストのセットアップが複雑になったりする問題がありました。特に、複数のファイルから構成されるテストや、特定のディレクトリ構造を必要とするテストの場合、all.bashrun.goといったGoの標準テストスクリプトでは実行が困難なケースがありました。

Go issue #4139は、このようなテストの実行と管理に関する課題に対処するためのものでした。このIssueの目的は、テストの依存関係を明確にし、テストのセットアップを簡素化するために、テストを専用のディレクトリ(*.dir)に隔離する新しい規約を導入することでした。これにより、テストの実行がより予測可能になり、テストフレームワークによる自動化が容易になります。

このコミットは、そのIssueの解決に向けた具体的なステップであり、既存のテストを新しいrundir/compiledir規約に移行することで、テストスイート全体の整合性と保守性を向上させています。

前提知識の解説

このコミットを理解するためには、以下のGo言語のテストに関する概念と規約について知っておく必要があります。

Go言語のテストの基本

Go言語では、テストは_test.goというサフィックスを持つファイルに記述されます。go testコマンドは、これらのファイルを自動的に検出し、テストを実行します。Goのテストは、通常、testingパッケージを利用して記述されます。

rundircompiledirerrorcheckdir規約

これらは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.goall.bash

  • test/run.go: Go言語のテストスイートを実行するための主要なスクリプトです。このスクリプトは、Goリポジトリ内の様々なテストファイルを検出し、適切な方法で実行します。rundircompiledirなどのディレクティブを解釈し、それに応じてテストのコンパイルや実行環境をセットアップします。
  • all.bash: Go言語のビルドとテストを全て実行するためのシェルスクリプトです。通常、Goのソースコードを変更した後に、全てのテストがパスすることを確認するために実行されます。test/run.goを呼び出してテストスイートを実行します。

このコミットでは、test/run.go内のskipOkayマップが更新されています。これは、特定のテストがall.bashによって直接実行されるのではなく、新しいrundir/compiledir規約に従ってtest/run.goによって処理されるようになったため、従来のスキップリストから削除されたことを意味します。

技術的詳細

このコミットの技術的な詳細を掘り下げると、主に以下の点が挙げられます。

  1. テストファイルのディレクトリ構造への移行:

    • 従来のテストファイル(例: 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)が配置されます。
  2. テストディレクティブの導入:

    • 各テストファイルの先頭に// rundir// compiledir、または// errorcheckdirといったコメントが追加されています。これらはGoのテストランナーに対する指示として機能します。
    • 例えば、test/fixedbugs/bug191.goには// rundircmpoutが追加されています。これはrundircmpout(出力比較)を組み合わせたディレクティブで、bug191.dir/main.goを実行し、その出力をbug191.outと比較することを意味します。
    • test/fixedbugs/bug382.goには// compiledirが追加され、test/fixedbugs/bug424.goには// rundirが追加されています。
    • test/import2.gotest/import4.goにはそれぞれ// compiledir// errorcheckdirが追加されています。
  3. 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リストから削除されています。
  4. テストの自己完結性:

    • 新しい規約により、各テストは自身の実行に必要な全てのファイルを専用のディレクトリ内に持つため、より自己完結的になります。これにより、テストの依存関係が明確になり、テストのセットアップやデバッグが容易になります。
    • 例えば、test/fixedbugs/bug424.dir/main.goは、libパッケージをインポートしていますが、このlibパッケージもbug424.dir/lib.goとして同じディレクトリ内に存在することが期待されます(このコミットのdiffにはlib.goの追加は含まれていませんが、規約上はそうあるべきです)。

これらの変更は、Go言語のテストインフラストラクチャをよりモジュール化し、スケーラブルにするための重要なステップです。テストの実行ロジックがテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。

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

このコミットにおけるコアとなるコードの変更は、主に以下のファイル群にわたります。

  1. test/fixedbugs/bug191.dir/main.go の新規作成と test/fixedbugs/bug191.go の変更:

    • test/fixedbugs/bug191.dir/main.go が新規作成され、元のbug191.gomainパッケージのコードが移動されています。このファイルは、ドットインポートのバグをテストするものです。
    • test/fixedbugs/bug191.go は、// rundircmpout ディレクティブとpackage ignoredのみを含むように変更されています。
  2. 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のみを含むように変更されています。
  3. 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のみを含むように変更されています。
  4. test/import2.dir/import2.go の新規作成と test/import2.go の変更:

    • test/import2.dir/import2.go が新規作成され、元のimport2.goのコードが移動されています。このファイルは、エクスポートされた変数と関数の様々な宣言をテストします。
    • test/import2.go は、// compiledir ディレクティブとpackage ignoredのみを含むように変更されています。
  5. test/import3.go から test/import2.dir/import3.go へのリネームと変更:

    • test/import3.gotest/import2.dir/import3.go へリネームされ、// NOTE: This test is not run by 'run.go' ... のようなコメントが削除されています。
  6. test/import4.dir/empty.go および test/import4.dir/import4.go の新規作成と test/import4.go の変更:

    • test/import4.dir/empty.gotest/import4.dir/import4.go が新規作成され、元のimport4.goのコードが移動されています。import4.goは、様々な種類の「インポートされたが使用されていない」エラーがコンパイラによって捕捉されることを検証します。
    • test/import4.go は、// errorcheckdir ディレクティブとpackage ignoredのみを含むように変更されています。
  7. test/method4.dir/prog.go の新規作成と test/method4.go の変更:

    • test/method4.dir/prog.go が新規作成され、元のmethod4.goのコードが移動されています。このテストは、引数を持つメソッド式をテストします。
    • test/method4.go は、// rundir ディレクティブとpackage ignoredのみを含むように変更されています。
  8. test/method4a.go から test/method4.dir/method4a.go へのリネームと変更:

    • test/method4a.gotest/method4.dir/method4a.go へリネームされ、不要なコメントが削除されています。
  9. 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.goall.bashでは実行されない」という注意書きがあり、手動での実行が必要でした。

変更後 (test/fixedbugs/bug191.gotest/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.gotest/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.gobug424.dir/内のmain.goをコンパイルして実行するようになります。

これらの変更は、Goのテストスイートの保守性を大幅に向上させます。テストの実行方法がテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。これにより、テストの記述が簡素化され、テストの依存関係が明確になり、テストフレームワークの柔軟性が向上します。また、all.bashrun.goといった上位のテストスクリプトが、個々のテストの実行詳細を意識することなく、統一された方法でテストを処理できるようになります。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (testingパッケージ): https://pkg.go.dev/testing
  • Go言語のテストに関する議論やドキュメント (GoのIssueトラッカーやメーリングリストのアーカイブ):
    • Go issue #4139のコメントスレッド
    • Goのテストフレームワークの進化に関するブログ記事や発表資料 (一般的な情報源として)
  • Go言語のソースコード (特にsrc/cmd/go/test.gotest/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.gotest/fixedbugs/bug382.gotest/fixedbugs/bug424.gotest/import2.gotest/import4.gotest/method4.go)が、それぞれ対応するディレクトリ構造(例: test/fixedbugs/bug191.dir/)に移動され、テストの実行方法が変更されています。また、test/run.goファイル内のテストスキップリストも更新されています。

変更の背景

Go言語のテストフレームワークは進化を続けており、より堅牢で管理しやすいテスト環境を構築するための改善が常に行われています。このコミットの背景には、Goのテスト実行メカニズムの標準化と効率化があります。

従来のGoテストでは、テストファイルが単一のディレクトリに配置され、テストのコンパイルや実行に必要な補助ファイル(例えば、インポートされるパッケージのソースコードなど)も同じディレクトリに置かれることがありました。しかし、これによりテストの依存関係が不明瞭になったり、テストのセットアップが複雑になったりする問題がありました。特に、複数のファイルから構成されるテストや、特定のディレクトリ構造を必要とするテストの場合、all.bashrun.goといったGoの標準テストスクリプトでは実行が困難なケースがありました。

Go issue #4139は、このようなテストの実行と管理に関する課題に対処するためのものでした。このIssueの目的は、テストの依存関係を明確にし、テストのセットアップを簡素化するために、テストを専用のディレクトリ(*.dir)に隔離する新しい規約を導入することでした。これにより、テストの実行がより予測可能になり、テストフレームワークによる自動化が容易になります。

このコミットは、そのIssueの解決に向けた具体的なステップであり、既存のテストを新しいrundir/compiledir規約に移行することで、テストスイート全体の整合性と保守性を向上させています。

前提知識の解説

このコミットを理解するためには、以下のGo言語のテストに関する概念と規約について知っておく必要があります。

Go言語のテストの基本

Go言語では、テストは_test.goというサフィックスを持つファイルに記述されます。go testコマンドは、これらのファイルを自動的に検出し、テストを実行します。Goのテストは、通常、testingパッケージを利用して記述されます。

rundircompiledirerrorcheckdir規約

これらは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.goall.bash

  • test/run.go: Go言語のテストスイートを実行するための主要なスクリプトです。このスクリプトは、Goリポジトリ内の様々なテストファイルを検出し、適切な方法で実行します。rundircompiledirなどのディレクティブを解釈し、それに応じてテストのコンパイルや実行環境をセットアップします。
  • all.bash: Go言語のビルドとテストを全て実行するためのシェルスクリプトです。通常、Goのソースコードを変更した後に、全てのテストがパスすることを確認するために実行されます。test/run.goを呼び出してテストスイートを実行します。

このコミットでは、test/run.go内のskipOkayマップが更新されています。これは、特定のテストがall.bashによって直接実行されるのではなく、新しいrundir/compiledir規約に従ってtest/run.goによって処理されるようになったため、従来のスキップリストから削除されたことを意味します。

技術的詳細

このコミットの技術的な詳細を掘り下げると、主に以下の点が挙げられます。

  1. テストファイルのディレクトリ構造への移行:

    • 従来のテストファイル(例: 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)が配置されます。
  2. テストディレクティブの導入:

    • 各テストファイルの先頭に// rundir// compiledir、または// errorcheckdirといったコメントが追加されています。これらはGoのテストランナーに対する指示として機能します。
    • 例えば、test/fixedbugs/bug191.goには// rundircmpoutが追加されています。これはrundircmpout(出力比較)を組み合わせたディレクティブで、bug191.dir/main.goを実行し、その出力をbug191.outと比較することを意味します。
    • test/fixedbugs/bug382.goには// compiledirが追加され、test/fixedbugs/bug424.goには// rundirが追加されています。
    • test/import2.gotest/import4.goにはそれぞれ// compiledir// errorcheckdirが追加されています。
  3. 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リストから削除されています。
  4. テストの自己完結性:

    • 新しい規約により、各テストは自身の実行に必要な全てのファイルを専用のディレクトリ内に持つため、より自己完結的になります。これにより、テストの依存関係が明確になり、テストのセットアップやデバッグが容易になります。
    • 例えば、test/fixedbugs/bug424.dir/main.goは、libパッケージをインポートしていますが、このlibパッケージもbug424.dir/lib.goとして同じディレクトリ内に存在することが期待されます(このコミットのdiffにはlib.goの追加は含まれていませんが、規約上はそうあるべきです)。

これらの変更は、Go言語のテストインフラストラクチャをよりモジュール化し、スケーラブルにするための重要なステップです。テストの実行ロジックがテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。

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

このコミットにおけるコアとなるコードの変更は、主に以下のファイル群にわたります。

  1. test/fixedbugs/bug191.dir/main.go の新規作成と test/fixedbugs/bug191.go の変更:

    • test/fixedbugs/bug191.dir/main.go が新規作成され、元のbug191.gomainパッケージのコードが移動されています。このファイルは、ドットインポートのバグをテストするものです。
    • test/fixedbugs/bug191.go は、// rundircmpout ディレクティブとpackage ignoredのみを含むように変更されています。
  2. 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のみを含むように変更されています。
  3. 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のみを含むように変更されています。
  4. test/import2.dir/import2.go の新規作成と test/import2.go の変更:

    • test/import2.dir/import2.go が新規作成され、元のimport2.goのコードが移動されています。このファイルは、エクスポートされた変数と関数の様々な宣言をテストします。
    • test/import2.go は、// compiledir ディレクティブとpackage ignoredのみを含むように変更されています。
  5. test/import3.go から test/import2.dir/import3.go へのリネームと変更:

    • test/import3.gotest/import2.dir/import3.go へリネームされ、// NOTE: This test is not run by 'run.go' ... のようなコメントが削除されています。
  6. test/import4.dir/empty.go および test/import4.dir/import4.go の新規作成と test/import4.go の変更:

    • test/import4.dir/empty.gotest/import4.dir/import4.go が新規作成され、元のimport4.goのコードが移動されています。import4.goは、様々な種類の「インポートされたが使用されていない」エラーがコンパイラによって捕捉されることを検証します。
    • test/import4.go は、// errorcheckdir ディレクティブとpackage ignoredのみを含むように変更されています。
  7. test/method4.dir/prog.go の新規作成と test/method4.go の変更:

    • test/method4.dir/prog.go が新規作成され、元のmethod4.goのコードが移動されています。このテストは、引数を持つメソッド式をテストします。
    • test/method4.go は、// rundir ディレクティブとpackage ignoredのみを含むように変更されています。
  8. test/method4a.go から test/method4.dir/method4a.go へのリネームと変更:

    • test/method4a.gotest/method4.dir/method4a.go へリネームされ、不要なコメントが削除されています。
  9. 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.goall.bashでは実行されない」という注意書きがあり、手動での実行が必要でした。

変更後 (test/fixedbugs/bug191.gotest/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.gotest/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.gobug424.dir/内のmain.goをコンパイルして実行するようになります。

これらの変更は、Goのテストスイートの保守性を大幅に向上させます。テストの実行方法がテストファイル自体から分離され、テストランナーがディレクティブに基づいて自動的に適切な環境を構築するようになります。これにより、テストの記述が簡素化され、テストの依存関係が明確になり、テストフレームワークの柔軟性が向上します。また、all.bashrun.goといった上位のテストスクリプトが、個々のテストの実行詳細を意識することなく、統一された方法でテストを処理できるようになります。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (testingパッケージ): https://pkg.go.dev/testing
  • Go言語のテストに関する議論やドキュメント (GoのIssueトラッカーやメーリングリストのアーカイブ):
    • Go issue #4139のコメントスレッド
    • Goのテストフレームワークの進化に関するブログ記事や発表資料 (一般的な情報源として)
  • Go言語のソースコード (特にsrc/cmd/go/test.gotest/run.go): Goのテストランナーの実装を理解するために参照。
  • Go言語のテスト規約に関する非公式な情報源 (Stack Overflow, 技術ブログなど): rundir, compiledir, errorcheckdirに関する具体的な使用例や解説。