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

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

このコミットは、Go言語のテストスイートにおける重要な変更を記録しています。具体的には、既存のテストの一部を、Goプロジェクトの標準的なテスト実行ツールである run.go を介して実行できるように変換しています。これにより、テストの実行方法が統一され、テストの信頼性と保守性が向上します。

コミット

commit dda1b560ec03e3c5da82bef67322f6f4d16cd7eb
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date:   Wed Oct 10 22:35:27 2012 +0200

    test: convert tests to run.go whenever possible.
    
    The other tests either need a complex procedure
    or are architecture- or OS-dependent.
    
    Update #4139.
    
    R=golang-dev, daniel.morsing, iant
    CC=golang-dev
    https://golang.org/cl/6618062

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

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

元コミット内容

test: convert tests to run.go whenever possible.

The other tests either need a complex procedure
or are architecture- or OS-dependent.

Update #4139.

R=golang-dev, daniel.morsing, iant
CC=golang-dev
https://golang.org/cl/6618062

変更の背景

Go言語のテストスイートは、プロジェクトの健全性を維持するために不可欠です。しかし、初期のGoプロジェクトでは、テストの実行方法が統一されておらず、一部のテストは特定のシェルスクリプト (./run など) を介して手動で実行する必要がありました。これは、テストの自動化やCI/CDパイプラインへの統合を困難にし、開発者がすべてのテストが実行されていることを確認する手間を増やしていました。

このコミットの背景には、Goのテストインフラストラクチャを改善し、より多くのテストを run.go という単一のツールで管理・実行できるようにするという目的があります。run.go はGoの標準的なテスト実行フレームワークであり、これにテストを統合することで、テストの発見、実行、レポートがより効率的になります。

コミットメッセージにある「The other tests either need a complex procedure or are architecture- or OS-dependent.」という記述は、当時 run.go で実行できないテストが存在した理由を示しています。これらのテストは、特定の環境設定、外部依存関係、またはOS/アーキテクチャ固有の動作を必要とするため、単純に run.go に移行することが困難でした。このコミットは、可能な限り多くのテストを run.go に移行することで、テストスイート全体の統一性を高めようとしています。

また、Update #4139 という記述から、この変更がGoのIssueトラッカーの特定の課題に関連していることがわかります。Issue #4139は「cmd/go: make go test run all tests」というタイトルで、go test コマンドがすべてのテストを実行するように改善することを目的としていました。このコミットは、その目標達成に向けた一歩として、run.go へのテスト統合を進めています。

前提知識の解説

このコミットを理解するためには、以下のGo言語のテストに関する前提知識が必要です。

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

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

  3. run.go (Goプロジェクト内部のテスト実行ツール): Go言語のソースコードリポジトリ(golang/go)には、test/run.go という特別なテスト実行ツールが存在します。これは、Goの標準的な go test コマンドではカバーしきれない、より複雑なテストシナリオ(例えば、複数のパッケージにまたがるテスト、コンパイルエラーを期待するテスト、特定のビルドタグを必要とするテストなど)を管理・実行するために使用されます。 run.go は、テストファイルの先頭に記述された特別なコメント(例: // rundir, // errorcheckdir, // compiledir)を解析し、それに基づいてテストの実行方法を決定します。

    • // rundir: テストを特定のディレクトリ内で実行することを示します。
    • // errorcheckdir: コンパイルエラーを期待するテストであることを示し、エラーメッセージのチェックを行います。
    • // compiledir: コンパイルが成功することを期待するテストであることを示します。 run.go は、これらのディレクティブに基づいて、テストのコンパイル、実行、出力の検証を行います。
  4. skipOkay マップ: test/run.go の内部には skipOkay というマップが存在します。このマップは、run.go が通常はスキップするが、特定の理由でスキップしても問題ない(または、run.go 以外の方法で実行される)テストファイルのリストを保持していました。このコミットでは、テストが run.go で実行可能になったため、このマップから該当するエントリが削除されています。

  5. Goのパッケージシステムとインポート: Goのコードはパッケージに分割され、他のパッケージのコードを import ステートメントで利用します。このコミットで変更されているテストの一部は、複数のパッケージにまたがるインポートや、パッケージ間の可視性(エクスポートされていないメソッドなど)に関するものです。

  6. インターフェースの埋め込み (Embedded Interfaces): Goのインターフェースは、他のインターフェースを埋め込むことができます。これにより、埋め込まれたインターフェースのメソッドセットが、埋め込み元のインターフェースのメソッドセットに含まれるようになります。このコミットで変更されている test/interface/embed1.go 関連のテストは、この機能に関連しています。

  7. 可変長引数関数 (Variadic Functions): Goの関数は、引数の数を可変にすることができます(例: func Sum(args ...int) int)。このコミットで変更されている test/ddd2.go 関連のテストは、パッケージ境界を越えた可変長引数関数の動作に関連しています。

  8. gccgo: gccgo は、GCC(GNU Compiler Collection)をバックエンドとして使用するGoコンパイラです。Goには公式のコンパイラ(gc)の他に、gccgo も存在し、異なるコンパイラでの動作確認も重要です。test/fixedbugs/bug437.go 関連のテストは、gccgo で発生していたリンクエラーの修正に関連しています。

技術的詳細

このコミットの技術的詳細は、主に以下の点に集約されます。

  1. テストファイルの構造化と移動: 多くのテストファイルが、元の単一ファイルから、ddd2.dir/, fixedbugs/bug437.dir/, interface/embed1.dir/, interface/private.dir/, interface/recursive1.dir/ といった新しいディレクトリ構造に移動されています。これは、run.go がディレクトリ単位でテストを管理し、関連するファイルをまとめて処理するための準備と考えられます。例えば、ddd2.goddd3.go は、可変長引数関数がパッケージ境界を越えて動作するかをテストするために、ddd2.dir ディレクトリにまとめられています。

  2. run.go ディレクティブの導入: 移動されたテストファイルの多くは、元のファイルからテストコードが削除され、代わりに新しいディレクトリ内のファイルにテストコードが記述されています。そして、元のファイル(または新しいディレクトリ内のメインのテストファイル)の先頭に // rundir// errorcheckdir といった run.go ディレクティブが追加されています。

    • test/ddd2.go// rundir に変更され、実際のテストロジックは test/ddd2.dir/ddd2.gotest/ddd2.dir/ddd3.go に分割されました。これは、可変長引数関数がパッケージ境界を越えて動作するかをテストするものです。
    • test/fixedbugs/bug437.go// rundir に変更され、テストロジックは test/fixedbugs/bug437.dir/x.go に移動されました。このテストは、異なるパッケージで定義された型を、第三のパッケージで定義されたインターフェース(隠されたメソッドを持つ)に変換する際の gccgo のリンクエラーを修正するためのものです。
    • test/interface/embed1.go// rundir に変更され、テストロジックは test/interface/embed1.dir/embed1.go に移動されました。これは、埋め込みインターフェース型がローカルメソッドを持つことができるかをテストします。
    • test/interface/private.go// errorcheckdir に変更され、テストロジックは test/interface/private.dir/prog.go に移動されました。このテストは、エクスポートされていないメソッドがパッケージ外から見えないことを確認するためのもので、コンパイルエラーを期待します。
    • test/interface/recursive1.go// compiledir に変更され、テストロジックは test/interface/recursive1.dir/recursive1.gotest/interface/recursive1.dir/recursive2.go に移動されました。これは、相互再帰的な型定義がインポートされ使用されることをテストします。
  3. skipOkay マップからのエントリ削除: test/run.go ファイルでは、skipOkay マップから以下のエントリが削除されています。

    • "ddd3.go"
    • "interface/embed1.go"
    • "interface/private.go"
    • "interface/recursive2.go"
    • "fixedbugs/bug437.go" これは、これらのテストが run.go で適切に実行されるようになったため、もはやスキップする必要がなくなったことを意味します。これにより、run.go がGoのテストスイートのより包括的な実行ツールとしての役割を強化しています。

これらの変更は、Goのテストインフラストラクチャの進化を示しており、テストの自動化と信頼性を向上させるための継続的な取り組みの一環です。

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

このコミットにおけるコアとなるコードの変更箇所は、主に以下のファイルとディレクトリに分散しています。

  1. test/run.go:

    • skipOkay マップから、ddd3.go, interface/embed1.go, interface/private.go, interface/recursive2.go, fixedbugs/bug437.go のエントリが削除されています。これは、これらのテストが run.go で実行可能になったことを示します。
  2. test/ddd2.dir/ ディレクトリの新規作成とファイル移動/作成:

    • test/ddd2.dir/ddd2.go が新規作成され、test/ddd2.go の一部のコードが移動されています。
    • test/ddd3.gotest/ddd2.dir/ddd3.go にリネーム・移動されています。
    • test/ddd2.go の内容が大幅に削減され、// rundir ディレクティブが追加されています。
  3. test/fixedbugs/bug437.dir/ ディレクトリの新規作成とファイル移動/作成:

    • test/fixedbugs/bug437.dir/x.go が新規作成され、test/fixedbugs/bug437.go のテストコードが移動されています。
    • test/fixedbugs/bug437.go の内容が大幅に削減され、// rundir ディレクティブが追加されています。
  4. test/interface/embed1.dir/ ディレクトリの新規作成とファイル移動/作成:

    • test/interface/embed0.gotest/interface/embed1.dir/embed0.go にリネーム・移動されています。
    • test/interface/embed1.dir/embed1.go が新規作成され、test/interface/embed1.go のテストコードが移動されています。
    • test/interface/embed1.go の内容が大幅に削減され、// rundir ディレクティブが追加されています。
  5. test/interface/private.dir/ ディレクトリの新規作成とファイル移動/作成:

    • test/interface/private1.gotest/interface/private.dir/private1.go にリネーム・移動されています。
    • test/interface/private.dir/prog.go が新規作成され、test/interface/private.go のテストコードが移動されています。
    • test/interface/private.go の内容が大幅に削減され、// errorcheckdir ディレクティブが追加されています。
  6. test/interface/recursive1.dir/ ディレクトリの新規作成とファイル移動/作成:

    • test/interface/recursive1.dir/recursive1.go が新規作成され、test/interface/recursive1.go の一部のコードが移動されています。
    • test/interface/recursive2.gotest/interface/recursive1.dir/recursive2.go にリネーム・移動されています。
    • test/interface/recursive1.go の内容が大幅に削減され、// compiledir ディレクティブが追加されています。

これらの変更は、テストコードを run.go が処理しやすいように再編成し、適切なディレクティブを付与することで、テスト実行の自動化と統一化を図っています。

コアとなるコードの解説

このコミットのコアとなる変更は、Goのテストスイートの実行方法を標準化し、run.go を中心としたテストインフラストラクチャへの移行を推進している点にあります。

具体的には、各テストケースが独立したディレクトリに配置され、そのディレクトリ内のメインのテストファイル(または元のテストファイル)に run.go が解釈する特別なコメント(ディレクティブ)が追加されています。

例えば、test/ddd2.go の変更を見てみましょう。 元の test/ddd2.go は、可変長引数関数 Sum を定義していました。そして、test/ddd3.go がこの Sum 関数をインポートして使用するテストでした。これらは、run.go ではなく、手動でコンパイル・実行する必要がありました。

変更後、test/ddd2.go は以下のように簡略化され、// rundir ディレクティブが追加されました。

// rundir

// Copyright 2010 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.

// Test that variadic functions work across package boundaries.

package ignored

そして、実際のテストロジックは test/ddd2.dir/ddd2.gotest/ddd2.dir/ddd3.go に分割されました。

test/ddd2.dir/ddd2.go (新規ファイル):

// Copyright 2010 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.

// This file is compiled and then imported by ddd3.go.

package ddd

func Sum(args ...int) int {
	s := 0
	for _, v := range args {
		s += v
	}
	return s
}

test/ddd2.dir/ddd3.go (test/ddd3.go からリネーム・移動):

// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license can be found in the LICENSE file.

(注: ddd3.go の具体的なテストコードはdiffには含まれていませんが、ddd2.goSum 関数をインポートして使用するテストロジックがここに含まれると推測されます。)

この変更により、run.gotest/ddd2.go// rundir ディレクティブを読み取り、test/ddd2.dir/ ディレクトリ内のGoファイルをコンパイル・実行するようになります。これにより、可変長引数関数がパッケージ境界を越えて正しく動作するかどうかを、run.go の自動テストスイートの一部として検証できるようになりました。

同様に、他のテストケースも // rundir, // errorcheckdir, // compiledir といったディレクティブと共に新しいディレクトリに移動され、run.go の管理下に置かれました。

test/run.go から skipOkay エントリが削除されたことは、これらのテストがもはや特別な扱いを必要とせず、run.go の標準的なテスト実行フローに組み込まれたことを明確に示しています。

このコミットは、Goのテストインフラストラクチャをより堅牢で自動化されたものにするための、体系的なリファクタリングの一環と言えます。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント: https://go.dev/
  • Goの testing パッケージ: https://pkg.go.dev/testing
  • Goのソースコードリポジトリ: https://github.com/golang/go
  • Goのテストインフラストラクチャに関する一般的な情報源 (例: run.go の役割に関するブログ記事やディスカッションなど) - 今回のコミットは古いものであり、run.go の詳細な公式ドキュメントは公開されていないため、Goのソースコード内のコメントや関連するコミット履歴から情報を推測しました。