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

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

このコミットは、Go言語のgo testコマンドにおけるテスト実行の挙動を変更するものです。具体的には、Example(例示コード)の実行を制御するための-test.exampleフラグを廃止し、既存の-test.runフラグがテストだけでなくExampleもフィルタリングできるように拡張されました。これにより、テストとExampleの実行制御が一元化され、コマンドラインインターフェースが簡素化されています。

コミット

cmd/go: drop -example, apply -run to examples
Once more, with feeling.

R=golang-dev, gri
CC=golang-dev
https://golang.org/cl/5698080

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

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

元コミット内容

commit ec15046a8d7aea1bc8f89c5ff8006c5244e76ebc
Author: Rob Pike <r@golang.org>
Date:   Tue Feb 28 08:33:06 2012 +1100

    cmd/go: drop -example, apply -run to examples
    Once more, with feeling.

    R=golang-dev, gri
    CC=golang-dev
    https://golang.org/cl/5698080

変更の背景

この変更の背景には、GoのテストフレームワークにおけるExampleの扱いと、コマンドラインインターフェースの一貫性の向上が挙げられます。以前は、go testコマンドでテスト関数を正規表現でフィルタリングするために-test.runフラグが使用され、Example関数をフィルタリングするためには-test.exampleフラグが別途存在していました。

しかし、テストとExampleはどちらもコードの動作を検証し、ドキュメント化する目的で使われる類似の概念です。これらを異なるフラグで制御することは、ユーザーにとって混乱を招く可能性があり、またコマンドラインオプションの冗長性にも繋がります。コミットメッセージにある「Once more, with feeling.」という表現は、この変更が以前にも議論されたり、試みられたりした経緯があることを示唆しています。おそらく、テストとExampleのフィルタリングを統合することで、より直感的で使いやすいgo testコマンドを提供しようという意図があったと考えられます。

この統合により、ユーザーは単一の-test.runフラグでテストとExampleの両方を柔軟に選択して実行できるようになり、開発体験が向上します。

前提知識の解説

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

  • go testコマンド: Go言語の標準テストツールであり、パッケージ内のテスト関数、ベンチマーク関数、およびExample関数を実行するために使用されます。
  • テスト関数 (TestXxx): func TestXxx(t *testing.T)というシグネチャを持つ関数で、コードの正確性を検証します。
  • ベンチマーク関数 (BenchmarkXxx): func BenchmarkXxx(b *testing.B)というシグネチャを持つ関数で、コードのパフォーマンスを測定します。
  • Example関数 (ExampleXxx): func ExampleXxx()またはfunc ExampleXxx_Yyy()というシグネチャを持つ関数で、パッケージの使用例を示します。これらの関数は、go docコマンドで生成されるドキュメントに表示され、またgo testによって実行され、出力が期待される出力と一致するかどうかが検証されます。これにより、ドキュメントとコードの整合性が保たれます。
  • testingパッケージ: Goの標準ライブラリの一部であり、テスト、ベンチマーク、Exampleを記述するための型と関数を提供します。
  • -runフラグ: go testコマンドのオプションの一つで、実行するテスト関数やベンチマーク関数を正規表現でフィルタリングするために使用されます。例えば、go test -run "Foo"は名前に"Foo"を含むテストのみを実行します。
  • フラグの伝播: go testコマンドに渡されるフラグの一部は、テストバイナリに内部的に伝播されます。例えば、-test.vはテストバイナリの-vフラグとして解釈されます。

このコミットは、特に-test.runとExample関数の連携に焦点を当てています。

技術的詳細

このコミットは、go testコマンドのExampleフィルタリングロジックを再構築し、-test.exampleフラグを削除して-test.runフラグにその機能を集約しています。

具体的な変更点は以下の通りです。

  1. src/cmd/go/test.goの変更:

    • go testコマンドのヘルプメッセージから-test.exampleフラグに関する記述が削除されました。これは、このフラグがユーザーに公開されなくなることを意味します。
  2. src/cmd/go/testflag.goの変更:

    • go testコマンドが内部的にテストバイナリに渡すフラグのリストから-test.exampleが削除されました。これにより、goコマンドはもはや-test.exampleを認識せず、テストバイナリに渡すこともありません。
  3. src/pkg/testing/example.goの変更:

    • flagパッケージのインポートが削除されました。これは、matchExamplesというグローバル変数が削除されたためです。
    • matchExamplesというflag.Stringで定義されていた正規表現マッチング用の変数が削除されました。
    • RunExamples関数内でExampleをフィルタリングする際に、以前は*matchExamples-test.exampleの値)を使用していた箇所が、*match-test.runの値)を使用するように変更されました。
    • エラーメッセージも-test.exampleに関するものから-test.runに関するものに修正されました。
    • RunExamples関数の冒頭にあった、-test.runが設定されている場合にExampleを実行しないというロジックが削除されました。これにより、-test.runが設定されていてもExampleが実行されるようになります。
  4. src/pkg/testing/testing.goの変更:

    • match変数のコメントが更新され、「regular expression to select tests to run」から「regular expression to select tests and examples to run」に変更されました。これは、-test.runフラグの役割が拡張されたことを明確に示しています。

これらの変更により、go test -run <pattern>という単一のコマンドで、テスト関数とExample関数の両方を正規表現パターンに基づいてフィルタリングできるようになりました。

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

このコミットのコアとなる変更は、src/pkg/testing/example.gosrc/pkg/testing/testing.goに集中しています。

src/pkg/testing/example.go:

--- a/src/pkg/testing/example.go
+++ b/src/pkg/testing/example.go
@@ -6,7 +6,6 @@ package testing
 
  import (
  	"bytes"
- 	"flag"
  	"fmt"
  	"io"
  	"os"
@@ -14,8 +13,6 @@ import (
  	"time"
  )
 
- var matchExamples = flag.String("test.example", "", "regular expression to select examples to run")
-
  type InternalExample struct {
  	Name   string
  	F      func()
@@ -23,9 +20,6 @@ type InternalExample struct {
  }
 
  func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
- 	if *match != "" && *matchExamples == "" {
- 		return // Don't run examples if testing is restricted: we're debugging.
- 	}
  	ok = true
 
  	var eg InternalExample
@@ -33,9 +27,9 @@ func RunExamples(matchString func(pat, str string) (bool, error), examples []Int
  	stdout, stderr := os.Stdout, os.Stderr
 
  	for _, eg = range examples {
- 		matched, err := matchString(*matchExamples, eg.Name)
+ 		matched, err := matchString(*match, eg.Name)
  		if err != nil {
- 			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.example: %s\\n", err)
+ 			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\\n", err)
  			os.Exit(1)
  		}
  		if !matched {

src/pkg/testing/testing.go:

--- a/src/pkg/testing/testing.go
+++ b/src/pkg/testing/testing.go
@@ -99,7 +99,7 @@ var (
 
  	// Report as tests are run; default is silent for success.
  	chatty         = flag.Bool("test.v", false, "verbose: print additional output")
- 	match          = flag.String("test.run", "", "regular expression to select tests to run")
+ 	match          = flag.String("test.run", "", "regular expression to select tests and examples to run")
  	memProfile     = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
  	memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
  	cpuProfile     = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")

コアとなるコードの解説

src/pkg/testing/example.goの変更は、Exampleの実行ロジックが-test.exampleフラグに依存しないようにするためのものです。

  1. flagパッケージの削除とmatchExamples変数の削除:

    • 以前はvar matchExamples = flag.String("test.example", "", ...)という行で-test.exampleフラグを定義し、その値を取得していました。この行が削除されたことで、testingパッケージはもはや-test.exampleフラグを直接処理しなくなりました。これに伴い、flagパッケージのインポートも不要になりました。
  2. RunExamples関数内のフィルタリングロジックの変更:

    • matched, err := matchString(*matchExamples, eg.Name)という行がmatched, err := matchString(*match, eg.Name)に変更されました。これは、Exampleの名前をフィルタリングする際に、以前は-test.exampleフラグの値(*matchExamples)を使用していたのを、-test.runフラグの値(*match)を使用するように切り替えたことを意味します。これにより、テストとExampleの両方が同じ正規表現パターンでフィルタリングされるようになります。
    • エラーメッセージも、-test.exampleに関するものから-test.runに関するものに更新され、ユーザーに正しいフラグの使用を促します。
  3. Example実行の早期リターンロジックの削除:

    • if *match != "" && *matchExamples == "" { return }という行が削除されました。このロジックは、-test.runが設定されているにもかかわらず-test.exampleが設定されていない場合にExampleの実行をスキップするものでした。このロジックが削除されたことで、-test.runが設定されていれば、そのパターンに基づいてExampleも実行されるようになりました。

src/pkg/testing/testing.goの変更は、-test.runフラグの役割の拡張をドキュメントレベルで明確にするものです。

  1. match変数のコメント更新:
    • match変数のコメントが「regular expression to select tests to run」から「regular expression to select tests and examples to run」に変更されました。これは、-test.runフラグがテストだけでなくExampleも対象とするようになったことを明示的に示しています。

これらの変更により、Goのテストフレームワークは、テストとExampleのフィルタリングを-test.runフラグに統合し、より一貫性のあるコマンドラインインターフェースを提供します。

関連リンク

  • Gerrit Change-ID: https://golang.org/cl/5698080
    • このリンクは、このコミットに対応するGoプロジェクトのGerritコードレビューページを示しています。ここには、変更に関する詳細な議論、レビューコメント、および関連する変更履歴が含まれている可能性があります。

参考にした情報源リンク

  • Go言語の公式ドキュメント(go testコマンド、testingパッケージに関する情報)
  • Go言語のソースコード(特にsrc/cmd/go/src/pkg/testing/ディレクトリ)
  • Gerrit Code Review (golang.org/cl/5698080) - このコミットの背景にある議論や以前の試みに関する情報が含まれている可能性があります。