t *testing.T は どこからやってくるの?
by
Kotaro Otaka
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
t *testing.T は どこからやってくるの? おーたかこーたろー / @otakakot 2026.04.22 Go Connect #12 The Go gopher was designed by Renée French.
Slide 2
Slide 2 text
ある日... #goconnect
Slide 3
Slide 3 text
データベースを使ったテストを 実装していたときの話 #goconnect
Slide 4
Slide 4 text
#goconnect
Slide 5
Slide 5 text
context canceled が発生して クリーンアップ処理に失敗 #goconnect
Slide 6
Slide 6 text
pgx パッケージを確認 #goconnect
Slide 7
Slide 7 text
t.Context() がキャンセルされている #goconnect
Slide 8
Slide 8 text
Bad! Good! #goconnect
Slide 9
Slide 9 text
t.Cleanup() では t.Context() は キャンセル済み! #goconnect
Slide 10
Slide 10 text
ところで... #goconnect
Slide 11
Slide 11 text
この t *testing.Tはどこからくるのか #goconnect
Slide 12
Slide 12 text
そもそも Go は main パッケージの main 関数が実行されるんでしょ #goconnect
Slide 13
Slide 13 text
#goconnect
Slide 14
Slide 14 text
なぜこのコードは動く ... ??? #goconnect
Slide 15
Slide 15 text
TextXxx は黒魔術...??? #goconnect
Slide 16
Slide 16 text
go test が動く仕組み #goconnect
Slide 17
Slide 17 text
おさらい #goconnect
Slide 18
Slide 18 text
#goconnect How to Write Go Code #Testing go test コマンドと testing パッケージ _test.go で終わるファイル func TestXXX(t *testing.T) 関数 https://go.dev/doc/code#Testing
Slide 19
Slide 19 text
#goconnect https://go.dev/doc/code#Testing
Slide 20
Slide 20 text
結論 #goconnect
Slide 21
Slide 21 text
#goconnect go test は ... テスト関数を呼び出す Go コード (main関数)を自動生成し コンパイルして実行している!
Slide 22
Slide 22 text
全体像 go test コマンド実行 ファイルの分類・関数の収集 _testmain.go の生成 ビルド 実行 #goconnect
Slide 23
Slide 23 text
注釈 ステップ数はおーたかによる解釈 #goconnect
Slide 24
Slide 24 text
サンプルコード #goconnect
Slide 25
Slide 25 text
go version Go 1.26.2 #goconnect
Slide 26
Slide 26 text
パッケージ構成 #goconnect
Slide 27
Slide 27 text
#goconnect
Slide 28
Slide 28 text
#goconnect
Slide 29
Slide 29 text
#goconnect
Slide 30
Slide 30 text
注釈 Go 本体のコードを引用しますが スライドの都合で省略しています 詳しくはURLを添付しているので そちらをご参照ください #goconnect
Slide 31
Slide 31 text
go test コマンド実行 #goconnect
Slide 32
Slide 32 text
概要 go コマンドが test サブコマンドを呼び テスト処理を実行する #goconnect
Slide 33
Slide 33 text
軽く解説 #goconnect
Slide 34
Slide 34 text
#goconnect ざっくりの流れ... go コマンド → test サブコマンド https://github.com/golang/go/blob/go1.26.2/src/cmd/go/main.go
Slide 35
Slide 35 text
#goconnect ざっくりの流れ... func runTest(...) に到達 https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/test/test.go
Slide 36
Slide 36 text
rutTest() 関数は パッケージごとに build → run → print を行うオーケストレーション #goconnect
Slide 37
Slide 37 text
build 処理にて テスト対象ファイル・関数を収集する Import(...) 関数に到達 #goconnect
Slide 38
Slide 38 text
#goconnect ファイルの分類・関数の収集
Slide 39
Slide 39 text
概要 ファイル名とパッケージ宣言で分類 テスト名をもとにテスト関数を収集 #goconnect
Slide 40
Slide 40 text
ファイルとパッケージの分類 ファイル名が _test.go で終わるか パッケージ宣言が _test で終わるか #goconnect
Slide 41
Slide 41 text
グルーピング ファイル名 パッケージ宣言 GoFiles ex) calc.go ex) package calc TestGoFiles ex) calc_test.go ex) package calc XTestGoFiles ex) calc_x_test.go ex) package calc_test #goconnect
Slide 42
Slide 42 text
グルーピング ファイル名 パッケージ宣言 GoFiles ex) calc.go ex) package calc TestGoFiles ex) calc_test.go ex) package calc XTestGoFiles ex) calc_x_test.go ex) package calc_test pxtest ptest #goconnect
Slide 43
Slide 43 text
各パッケージからテスト関数を AST により収集 #goconnect
Slide 44
Slide 44 text
#goconnect ptest, pxtest を for ループ https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L584-L593
Slide 45
Slide 45 text
#goconnect テスト関数を管理する構造体 https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L626-L638
Slide 46
Slide 46 text
#goconnect ファイル内の関数をループ https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L702-L773
Slide 47
Slide 47 text
#goconnect 命名規則チェック 関数の型チェック https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L702-L773
Slide 48
Slide 48 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L584-L593
Slide 49
Slide 49 text
#goconnect 型チェック ジェネリクス禁止 https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L775-L788
Slide 50
Slide 50 text
#goconnect 戻り値・引数チェック ポインタチェック 型名チェック https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L557-L579
Slide 51
Slide 51 text
以下のテスト関数を収集 ptest.TestAdd(t *testing.T) ptest.TestSub(t *testing.T) pxtest.TestAdd(t *testing.T) #goconnect
Slide 52
Slide 52 text
_testmain.go の生成 #goconnect
Slide 53
Slide 53 text
概要 テスト関数を実行する main () 関数を生成する #goconnect
Slide 54
Slide 54 text
Go Template を使ったコード生成 testFuncs 構造体を受け取る testmainTmpl #goconnect
Slide 55
Slide 55 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L790-L862
Slide 56
Slide 56 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L790-L862
Slide 57
Slide 57 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L790-L862
Slide 58
Slide 58 text
#goconnect Go Template によるコード生成 https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/load/test.go#L617-L624
Slide 59
Slide 59 text
生成されるテスト実行コード #goconnect
Slide 60
Slide 60 text
_testmain.go の確認方法 go test -work WORK=xxxx #goconnect
Slide 61
Slide 61 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/testing/testing.go#L2319-L2329
Slide 62
Slide 62 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/testing/testing.go#L2340-L2487
Slide 63
Slide 63 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/testing/testing.go#L2551-L2598
Slide 64
Slide 64 text
t *testing.T は自動生成するコードで テストを動かす MainStart(..).Run() 関数 からやってくる! #goconnect
Slide 65
Slide 65 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/testing/testing.go#L1876-L2042
Slide 66
Slide 66 text
ビルド #goconnect
Slide 67
Slide 67 text
概要 リスト化したパッケージをもとに 実行可能バイナリを生成する #goconnect
Slide 68
Slide 68 text
省略! go build と同じ仕組みを利用 バイナリの命名が異なる (.test が付与) #goconnect
Slide 69
Slide 69 text
実行 #goconnect
Slide 70
Slide 70 text
概要 生成したテストバイナリを 子プロセスとして実行 #goconnect
Slide 71
Slide 71 text
#goconnect https://github.com/golang/go/blob/go1.26.2/src/cmd/go/internal/test/test.go#L1435-L1774
Slide 72
Slide 72 text
テスト実行完了! #goconnect
Slide 73
Slide 73 text
まとめ #goconnect
Slide 74
Slide 74 text
#goconnect go test は黒魔術ではなく go template と AST を愚直に使った コード自動生成による main 関数の実行
Slide 75
Slide 75 text
2020.04 2021.04 2022.11 Kotaro Otaka おーたかこーたろー / @otakakot Web Engineer 新卒入社 Hello Golang! Web Engineer @株式会社ビットキー Gopher6年生 #goconnect
Slide 76
Slide 76 text
おわり またどこかで お会いしましょう!