Slide 1

Slide 1 text

go test -json そして testing.T.Attr id:utgwkk / @utgwkk (うたがわきき) 2025/8/31 Kyoto.go #63 オフラインLT会@マネフォ京都 #kyotogo 1

Slide 2

Slide 2 text

自己紹介 ● うたがわきき (@utgwkk) ● 株式会社はてな ○ Webアプリケーションエンジニア ● 好きなパッケージはreflect ● 最近はTypeScript書いてる 2

Slide 3

Slide 3 text

ここでアンケート ● Goでテストを書いたことがある? ● (挙手を促す) ● 雰囲気わかりました 3

Slide 4

Slide 4 text

アジェンダ ● go test -json について ● testing.T.Attr について 4

Slide 5

Slide 5 text

アジェンダ ● go test -json について ● testing.T.Attr について 5

Slide 6

Slide 6 text

ここでアンケート ● go testの-jsonオプションを知っている・ 使ったことがある? ● (挙手を促す) ● 雰囲気わかりました 6

Slide 7

Slide 7 text

go test -json ● テストの出力をJSON形式で得られる ● テスト結果をプログラマブルに解析・パース するのに便利 7

Slide 8

Slide 8 text

go test -v 8 === RUN TestDummy --- PASS: TestDummy (0.00s) PASS ok github.com/owner/repo 0.492s

Slide 9

Slide 9 text

go test -json {"Time":"2025-08-25T22:14:43.946504+09:00","Action":"start","Package":"github.com/owner/repo"} {"Time":"2025-08-25T22:14:44.522307+09:00","Action":"run","Package":"github.com/owner/repo","Test":"TestDummy "} {"Time":"2025-08-25T22:14:44.522455+09:00","Action":"output","Package":"github.com/owner/repo","Test":"TestDu mmy","Output":"=== RUN TestDummy\n"} {"Time":"2025-08-25T22:14:44.522499+09:00","Action":"output","Package":"github.com/owner/repo","Test":"TestDu mmy","Output":"--- PASS: TestDummy (0.00s)\n"} {"Time":"2025-08-25T22:14:44.522507+09:00","Action":"pass","Package":"github.com/owner/repo","Test":"TestDumm y","Elapsed":0} {"Time":"2025-08-25T22:14:44.522513+09:00","Action":"output","Package":"github.com/owner/repo","Output":"PASS \n"} {"Time":"2025-08-25T22:14:44.522989+09:00","Action":"output","Package":"github.com/owner/repo","Output":"ok \tgithub.com/owner/repo\t0.576s\n"} {"Time":"2025-08-25T22:14:44.52587+09:00","Action":"pass","Package":"github.com/owner/repo","Elapsed":0.579} 9

Slide 10

Slide 10 text

雰囲気を嗅ぎ取る 10 ● Actionに出力の種類が入っていそう ○ start/run/output/pass/(fail) ● Actionに応じて出力されるフィールドが変わ りそう ○ Test/Output/Elapsed

Slide 11

Slide 11 text

ちゃんとしたドキュメント ● https://pkg.go.dev/cmd/test2json ● test2jsonというコマンドでログ→JSONの変 換だけを行うこともできる ○ cat output.log | go tool test2json 11

Slide 12

Slide 12 text

go test -jsonの大まかな実装 ● テストのログを1行ずつパースしている ○ === RUN TestDummy ○ --- PASS: TestDummy (0.00s) ● cmd/internal/test2json 以下に実装がある 12

Slide 13

Slide 13 text

go test -jsonの活用方法 ● テストの実行結果を分かりやすく表示する ○ mfridman/tparse ○ gotestyourself/gotestsum 13

Slide 14

Slide 14 text

mfridman/tparse 14 画像は mfridman/tparse のREADMEから引用

Slide 15

Slide 15 text

15 画像は mfridman/tparse のREADMEから引用

Slide 16

Slide 16 text

16 画像は gotestyourself/gotestsum のREADMEから引用

Slide 17

Slide 17 text

小まとめ (go test -json) ● go testコマンドに-jsonオプションを渡すこ とでテストの結果をJSON形式で出力できる ● go test -jsonの出力をパースして整形する ツールがある 17

Slide 18

Slide 18 text

アジェンダ ● go test -json について ● testing.T.Attr について 18

Slide 19

Slide 19 text

Go 1.25 is released ● 👏🎉👏 ● (ここで拍手) 19

Slide 20

Slide 20 text

リリースノートを見る ● いろいろ増えたり変わったりしてますね ● そんな中、ふと目に入った新機能が…… 20

Slide 21

Slide 21 text

ふと目に入った新機能 >The new methods T.Attr, B.Attr, and F.Attr emit an attribute to the test log. An attribute is an arbitrary key and value associated with a test. https://go.dev/doc/go1.25#testingpkgtesting 21

Slide 22

Slide 22 text

これなに ● 日本語の記事がぜんぜん出てこない ● リリースノートの翻訳よりも深い情報が見つ からない 22

Slide 23

Slide 23 text

ググったら自分のCosenseが出てくる ● なかなか情報量が増えない ● 助けてくれ 23

Slide 24

Slide 24 text

たぶん最も詳しい日本語情報 ● 近頃の気になるGo testingパッケージ - Speaker Deck ● CA.go#16 LT大会 の実況ログからたどって何 とかたどり着いた ○ https://x.com/0xjj_official/status/1940000781 283074204 24

Slide 25

Slide 25 text

自分なりに調査してみる ● Attrっていうメソッドがあることは分かった ● 何もわからない ○ 生まれた経緯は? ○ 使い方は? ● とりあえず自分の言葉でまとめ直してみる 25

Slide 26

Slide 26 text

proposal探す testing: structured output for test attributes #43936 26

Slide 27

Slide 27 text

モチベーション ● go test -json によってGoのテストの出力を プログラマブルに解析・加工できて便利 ● テストのログにメタデータを含められると もっと便利になるんじゃないか 27

Slide 28

Slide 28 text

要するに? ● テストだって構造化ログにしたい ● ってこと? ○ 誰か教えて 28

Slide 29

Slide 29 text

proposalのタイムライン (ざっくり) ● 2021/1/27 issueが起票される ● 2023/7/20 議論が進みはじめる ● 2023/11/2 Russ Coxによって現行のメソッドシグネ チャが提案される ○ t.Attr(key, value string) ● 2025/4/3 proposalが受理される ● 2025/8/15 Go 1.25がリリースされる 29

Slide 30

Slide 30 text

制約 ● Attr(key, value string) ● keyは空白文字を含めない ● valueは改行 (CR, LF) を含めない ● 出力される順序の規定はない 30

Slide 31

Slide 31 text

t.Log() との棲み分け ● t.Log() のほうが人間には優しい ○ ログを出力したコードの行番号つき ○ だいたい何でも出力できる ● テストに対するメタデータを付与したいなら t.Attr() を使う 31

Slide 32

Slide 32 text

メタデータ is ● いくつかユースケースが示されている ○ テストのIDを埋め込む ○ 外部ストレージに出力したログのURLを埋める ● ツールとの連携が主なユースケース? 32

Slide 33

Slide 33 text

なぜ Attr(key string, value any) で はないのか ● slogには Any(key string, value any) という 関数があるけれども…… ○ だいたい何でもログ出力できる 33

Slide 34

Slide 34 text

なぜ Attr(key string, value any) で はないのか ● valueが任意の型だと、valueを文字列化 ・JSON encodeする必要がある ○ 全てのテストがencoding/jsonに依存するのは微妙 ○ 必要なときだけJSON encodeする方がいい ● (このあたりの議論をかいつまんだ) 34

Slide 35

Slide 35 text

Attrという語彙でピンと来た方へ ● log/slogにはAttrという型がある ○ 構造化ログのパラメータを表す ● log/slogが導入された辺りでproposalの議論 が進みはじめた 35

Slide 36

Slide 36 text

proposalのタイムライン (ざっくり) ● 2021/1/27 issueが起票される ● 2023/7/20 議論が進みはじめる ● 2023/11/2 Russ Coxによって現行のメソッドシグネ チャが提案される ○ t.Attr(key, value string) ● 2025/4/3 proposalが受理される ● 2025/8/15 Go 1.25がリリースされる 36

Slide 37

Slide 37 text

proposalのタイムライン (ざっくり) ● 2021/1/27 issueが起票される ● 2023/3/16 log/slogのproposalが受理される ● 2023/7/20 議論が進みはじめる ● 2023/11/2 Russ Coxによって現行のメソッドシグネ チャが提案される ○ t.Attr(key, value string) ● 2025/4/3 proposalが受理される ● 2025/8/15 Go 1.25がリリースされる 37

Slide 38

Slide 38 text

小まとめ (testing.T.Attr) ● Go 1.25 でtesting.T,B,FにAttrメソッドが追 加された ○ テストのログに構造化されたメタデータを埋めること ができる ● 利用方法はこちらに委ねられていそう ○ テスト結果をパースするツールでうまく使われる? 38

Slide 39

Slide 39 text

まとめ ● proposalの議論を追うとおもしろい ○ 慎重に議論が進められていることが分かる ● なぜこういうインターフェスなのか、その答 えはproposalにあるかもしれない ○ 謎が深まることもあるかもしれない 39

Slide 40

Slide 40 text

参考 ● test2json command - cmd/test2json - Go Packages ● Go 1.25 is released - The Go Programming Language ● Go 1.25 Release Notes - The Go Programming Language ● 近頃の気になるGo testingパッケージ - Speaker Deck ● testing: structured output for test attributes #43936 ● log/slog: structured, leveled logging #56345 40

Slide 41

Slide 41 text

おまけ (AI活用事例) ● NotebookLMにGitHubのissueをソースとし て渡す ○ URLを渡すよりも、GitHub APIでissueコメントを全 取得して渡すほうが精度が高い ○ Web UI上では省略されているコメントに大事なこと が書いてありがち 41

Slide 42

Slide 42 text

おまけ (AI活用事例) https://notebooklm.google.com/notebook/ c63be61a-6547-40e7-870f-8326f99b417d 42

Slide 43

Slide 43 text

おまけ (AI活用事例) ● NotebookLMの答えが正しいかどうかは自分 の目で確かめよう ○ 最終的には人間が英語を読む 43

Slide 44

Slide 44 text

おまけ (AI活用事例) ● GitHub公式のMCPサーバー実装がありそう ○ https://github.com/github/github-mcp-server ○ これを使うと手作業でissueコメントを取ってくるの すら不要になるのでは 44