メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

#64993declined

testing: allow examples the use of testing.T/B/F for test framework examples

ステータス変更: active declined

要約

AIによる要約であり、誤りを含む場合があります。

概要

testing パッケージのExample関数に *testing.T*testing.B*testing.F 型の引数を受け取る機能を追加し、テストフレームワークのサンプルコードをドキュメントとして公開できるようにすることを提案していました。

ステータス変更

activedeclined
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) として表示し、テスト実行時は通常のテスト関数と同様に動作させることを想定していました。

これによって何ができるようになるか

主に以下の用途を想定していました。

  1. テストフレームワーク・ライブラリのドキュメント例示: vmtestgo-cmp のようなテスト補助ライブラリが、*testing.T を使った実際の使用例をドキュメントとして公開できる
  2. testing パッケージ自体のドキュメント強化: testing.T.Fatalsynctest.Test の動作をExample関数で示せる
  3. 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 を利用できる可能性を提示しました

関連リンク