このブログは 2025 年新歓ブログリレー 47 日目 (4/22) の記事です。
22B のいくら・はむです。traPでは主にGo言語でサーバーアプリケーションを書いています。この記事では、Go 1.24 で追加された (*testing.common).Context
に関する静的解析ツールを作ったことについて書こうと思います。
(*testing.common).Context
とは
2025 年 2 月にリリースされた Go 1.24 で追加された機能の一つに、 (*testing.common).Context
メソッドがあります。このメソッドは、context.Context
を返す関数です。testing.common
というのは testing パッケージで定義されている構造体で、testing.T
とtesting.B
に埋め込まれています。そのため、この新しいメソッドはレシーバに*testing.T
と*testing.B
の 2 種類を取ることができます。このメソッドが返す context.Context
はテストが完了して Cleanup 関数が実行される前にキャンセルされます。
リリースノート https://tip.golang.org/doc/go1.24#testingpkgtesting

このメソッドは非常に便利で、テスト関数の中でのみ有効な context.Context
を何も考えずに使うことができます。今までは自分でキャンセル処理を書く必要があったので、大きな変化になります。
しかし、先ほど述べたように、このcontext.Context
は (*testing.common).Cleanup
が呼ばれる前にキャンセルされてしまいます。つまり、Cleanup 関数の中でこのcontext.Context
を使うと想定通り動かない可能性があります。この仕様を知らないとなかなか罠にはまりやすそうです。
静的解析ツール c3
そこで、c3
という静的解析ツールを開発しました。Context Cleanup Checker の頭文字から c3 です。
https://github.com/ikura-hamu/c3
このツールでは、(*testing.common).Cleanup
の中で (*testing.common).Context
が使われていた場合、警告が表示されます。
このツールをつくるにあたっては、skeleton というツールを使って雛形のコードを生成してから書きました。必要な要素があらかじめそろった状態で書き始められるのでとても楽でした。
https://github.com/gostaticanalysis/skeleton
また、この c3 は golangci-lint の Module Plugin System に対応しています。適切な設定を記述してカスタムバイナリをビルドすれば、golangci-lintに組み込んで使うことができます。
https://golangci-lint.run/plugins/module-plugins/
カスタムしたgolangci-lintが動いている様子
Modulu Plugin System については、以前僕が書いた記事も参考にしてください。

静的解析ツールを作るのは難しいですが、生成AIに相談しながら書くといい感じにできます。生成AIはコーナーケースを見つけるのは苦手なので、そこは人間がいい感じに対応しながらやるといいと思います。
静的解析ツールがあると開発の効率が大きく上がるので、これからも自分が欲しいと思ったものを積極的に作っていきたいです。c3もまだバグが残っているので、まずはそれを直したいです。
ぜひ GitHub のスターお願いします。
明日の新歓ブログリレー担当は @Oxojo くんと @jupiter_68 くんです。