testing: allow examples the use of testing.T/B/F for test framework examples
要約
概要
testing パッケージのExample関数に *testing.T、*testing.B、*testing.F 型の引数を受け取る機能を追加し、テストフレームワークのサンプルコードをドキュメントとして公開できるようにすることを提案していました。
ステータス変更
active → declined
2026年6月10日のProposal Review Meetingにおいて、@aclementsを筆頭とするコアチームが代替アプローチとなるissue #79808(任意のシグネチャを持つExample関数の許可)を優先することを決定し、議論を集約するためにこのproposalをクローズしました。
技術的背景
現状の問題点
テストフレームワーク・ライブラリの作者が pkg.go.dev 上でドキュメントとして表示できる実行可能なサンプルコードを書く際に、既存のExample関数は引数なしか // Output: コメントによるstdout検証のみしか対応していません。testing.TB を必要とするAPIのサンプルコードは、ダミーの testing.TB 実装を自前で用意するか、テストフレームワーク固有のコードを書く必要がありました。
// 問題: testing.TBが必要なAPIのExample(現在は不可能か、回避策が必要)
func ExampleFunctionname() {
// testing.T が使えないため、t.Logf のような呼び出しができない
fmt.Println("foobar")
// Output: foobar
}
testing/synctest パッケージが synctest.Run(func()) から synctest.Test(*testing.T, func(*testing.T)) に移行したことでも、Example関数内での synctest.Test 利用が困難になるという問題が生じていました。
提案された解決策
Example関数が以下の3つの形式を取れるよう拡張することを提案していました。
// 形式1: 既存の引数なし形式
func ExampleFunctionname() { ... }
// 形式2: *testing.T を引数として取る形式(本proposal)
func ExampleFunctionname(t *testing.T) {
t.Logf("foobar")
}
// 形式3: error を返す形式(関連proposal #21111 で検討中)
func ExampleFunctionname() error { ... }
*testing.T 引数を持つExample関数はドキュメント上で TestFunctionname(t *testing.T) として表示し、テスト実行時は通常のテスト関数と同様に動作させることを想定していました。
これによって何ができるようになるか
主に以下の用途を想定していました。
- テストフレームワーク・ライブラリのドキュメント例示:
vmtest、go-cmpのようなテスト補助ライブラリが、*testing.Tを使った実際の使用例をドキュメントとして公開できる testingパッケージ自体のドキュメント強化:testing.T.Fatalやsynctest.Testの動作をExample関数で示せるsynctest.Testを使ったExample関数: 時刻操作が必要なサンプルコードを再現性ある形で記述できる
コード例
// Before: testing.T が必要なAPIのExample(現在は不可能か、回避策が必要)
func ExampleT_Fatal() {
// testing.T を直接使えないため、動作を示すことができない
}
// After: 提案されていた形式
func ExampleT_Fatal(t *testing.T) {
t.Fatal("calling fatal fails the test")
// ドキュメント上は TestT_Fatal(t *testing.T) として表示される
}
議論のハイライト
// Output:コメントとの互換性:*testing.Tを引数に取る形式と// Output:コメントを同時に使う場合の扱いについて議論がありました。t.Logの出力はstdoutとは別であるため、// Output:はstdout出力のみを対象にすべきという意見(@neild)と、両者を排他にすべきという意見(@dolmen)が対立しました。最終的に @aclements は「完全に組み合わせ可能」という立場を示していました*testing.Bの有用性:*testing.BをExample関数の引数として許可する意義について検討されましたが、ベンチマークのサンプルコードへのニーズは限定的との意見が大勢でした- 実装が先決: @aclements は「提案の方向性は支持するが、go docでの表示形式が複雑なため、実装を先に見せてほしい」とコメントし、具体的な実装なしでの承認を保留していました
- 代替アプローチの浮上: 議論中に、任意のシグネチャ(引数あり・戻り値あり)のExample関数を
go testでは実行せずドキュメントのみに表示する代替案(#79808)が提示されました。この案では、実行が必要な場合はTestExampleXxxという対応するテスト関数を別途記述する形を取ります testing.Test関数の提案: @seankhliao は既存のtesting.Benchmark関数に相当するtesting.Test(func(t *T))関数を追加することで、テスト関数なしの通常のExample内でも*testing.Tを利用できる可能性を提示しました
関連リンク
- Proposal Issue github.com/golang/go
- Review Comment proposal review meeting
- Proposal Issue
- Review Minutes
- 代替Proposal #79808: testing: allow examples with any signature
- 関連Proposal #21111: testing: allow examples to return an error
- 関連Proposal #74009: go/doc,testing: add playable examples using a *testing.T context