🙌
【イベントレポート】テストしやすいコードとは?tenntenn氏、渋川氏、zoncoen氏に聞くGoテスト設計最前線
公開
2025-02-19
文章量
約3725字

Yard 編集部
Yardの編集部が、テック業界の最新トレンドや知見について発信します。
2025年1月30日、エンジニア向けサービス「Offers」が主催するオンラインイベント「テストしやすいコードとは?tenntenn氏、渋川氏、zoncoen氏に聞くGoテスト設計最前線」が開催されました。
Go言語界隈ではおなじみの@tenntenn氏、@shibu_jp(渋川)氏、そして@zoncoen氏という豪華登壇者が集結し、「どのようにテストしやすいコードを設計するか」や「E2E/インテグレーションテストとユニットテストのバランス」など、実践的な知見を余すところなく共有しました。
本記事では、各登壇者のLT(ライトニングトーク)の概要と、後半で行われたディスカッション&Q&Aセッションのハイライトをお届けします。
セッション1: 「読みやすいテーブル駆動テストとその実践」
登壇者: tenntenn氏(株式会社ニモ/バックエンドエンジニア)資料:
最初のLTでは、Goならではの“テーブル駆動テスト”にフォーカス。tenntenn氏は、Googleが公開しているスタイルガイドなどを引用しながら、「明確さ」「ロジックとテストケースの分離」「失敗時の情報量」を意識したテストコードの書き方を紹介しました。
- テーブル駆動テストの基本
- Goの公式ドキュメントでも解説されている、構造体スライス(またはマップ)でテストケースを列挙し、共通の検証ロジックに流し込む手法。
- 良いテーブルテストの条件
- テストケースとロジックを明確に切り分ける
- 「ケース同士の違い」が可視化できるようにする
- 後からテストケースを追加しやすい形を保つ
- 悪いパターン
- テストケース内にゴリゴリのロジックを書いてしまう
- 何でもかんでも一つのテーブルに詰め込みすぎ、差分が分かりにくい
- 実務への応用
- 十分に向き合えばテストの可読性は確保できるが、コピペ習慣やテストデータの扱いが乱雑になると一気に読みづらくなる。必要に応じてヘルパーやファイルベースのテスト(Golden fileなど)を活用することがカギ。
テーブルテスト自体はシンプルだが、なぜテーブルにするのか・どう差分を強調するかを意識しないと「ただの長いテストコード」になる点を強調。
エンジニア一人ひとりがテストと真摯に向き合う姿勢を促していました。
セッション2: 「ケーススタディに学ぶインテグレーションテストの課題とその解決策」
登壇者: zoncoen氏zoncoen(バックエンドエンジニア/元メルペイ)資料:
zoncoen氏は、マイクロサービスを多数運用する現場での“インテグレーションテスト”設計について事例紹介。
とりわけ「複数サービスを実際に接続した状態」でのテスト(シナリオテスト)を通じ、開発・QAをどのようにスムーズに回すかがテーマでした。
- 背景:マイクロサービス環境で壊れがち
- リリース前に開発環境がしばしば壊れる、チーム間の認識齟齬で接続先が動かない、という問題が頻出。
- プラットフォーム的アプローチ
シナリGo
という独自ツールを活用し、HTTPやgRPCなどのリクエストのシナリオを記述&実行- CI連携やローカル実行を意識したラッパーコマンドを用意し、誰でも素早くインテグレーションテストを書けるように工夫
- PRごとの環境生成
- Pull Request単位で新しいKubernetesデプロイを起動し、そこへテストリクエストを投げる「プルリクエストレプリケーションコントローラー」を導入。これにより、マージ前に「本番に近い状態」での結合テストが可能になった。
- 非同期ジョブのテスト
- バッチ的に実行されるジョブ処理をどうテストするかは難所だが、クラウドPub/Sub+プライベートクレームによるルーティングなどを駆使。実際に手動待ちすることなく、確実に非同期処理を呼び出して検証できる設計に。
「全サービスをモックせず、実際に結合するがゆえの課題は多いが、仕組みやツールを整備すればそこそこ解決できる」というメッセージは、多くのマイクロサービス現場のエンジニアに響く内容でした。
セッション3: 「(仮)多すぎるユニットテストは却ってよくない?私が実践しているテストコードのリファクタリング」
登壇者: 渋川氏(フューチャーアーキテクト)資料
「浅いモジュール」と「深いモジュール」という概念を引用しながら、プライベート関数のテストの扱い、不要なテスト削減の重要性など、やや“攻め”の視点で語られました。
- 浅いモジュール vs. 深いモジュール
- 浅いモジュール:公開APIが多いが内部実装が単純(例: Webレイヤーのハンドラー群)
- 深いモジュール:公開APIは少ないが内部が複雑(例: 正規表現ライブラリ、インタープリタ実装など)
- プライベートテストはいつまで必要?
- 最初はTDD的にプライベート関数もテストすることで設計を固める
- しかし上流APIが確定したら、最終的に“深いモジュール”でも「公開APIベースのテスト」にリファクタリングし、重複するプライベートテストは削除する
- テストケースが無駄に多いと開発効率が下がる
- バグ修正時にテストコードも一斉修正が必要になり、設計変更の障壁になる
- “価値”の低いテストを潔く捨てる判断も必要
- E2Eテストとのバランスフロントエンドでは “Testing Trophy” という概念が注目されているように、E2Eテストだけに寄せず、適度にユニット/インテグレーションテストを組み合わせるのがポイント。
渋川氏は「プライベート領域にも初期はテストを書いて設計を洗練させ、後から捨てることを前提にする」と語り、テストを“柔軟に手放せる設計”が長期的な保守性を高めると強調していました。
ディスカッション・Q&A ハイライト
3名のLTを受け、後半はOffers CTO 大谷氏がモデレーターとなり、視聴者からの質問も交えながらディスカッションが行われました。
- テストの可読性を下げない工夫は?
- テストケースとロジックを分離する
- “差分”がパッとわかる形(テーブル駆動やファイルベースなど)
- 必要に応じてテストごと分割し、名前に「成功系」「異常系」など意図を込める
- E2E(シナリオ)テストの実行時間が増大して困っている
- 意識的に“ノータ”をつける(優先度の高いシナリオだけをPRごとに回し、残りは定期実行)
- 並列実行を可能にする仕組み(Goの
T.Parallel()
など) - 全部をE2Eに寄せず、カバレッジはユニットテストやインテグレーションテストと適切に切り分ける
- 複数サービスが絡む機能でユニットテストだけでは見逃しが出る
- 「本番で試す」「本番に近い接続環境で試す」ことは現実的に不可欠
- そこをテスト環境で再現するなら、PRごとの環境デプロイやダイナミックルーティングなど、仕組みを整える必要がある
- Mockを多用すると安心感が低くなるケースも多いので、その線引きと運用ルールを明確化する
- プライベートテストの扱い
- プライベート関数をテストするか否かはフェーズによりけり
- 実装初期のフェーズはTDD的に詳細テストをしつつ、最終的に“捨てる”判断も視野に入れる
登壇者同士のやり取りを通じて、「テストを書けば全てOK」という単純な結論ではなく、テストの目的やユースケースを常に意識して“どこに責務を持たせるか”を検討することが大切だと再確認されました。
まとめ
本イベントは、Goエンジニア必見のテスト設計最前線として、三者三様のアプローチが披露されました。
- tenntenn:テーブル駆動テストをいかに読みやすく保つか。差分を分かりやすく、不要なロジックを持ち込まず、失敗時に必要十分な情報を返すのが鍵。
- 渋川氏:“深いモジュール”ではプライベートテストが一時的に増えがちだが、後でリファクタリングして“価値”のないテストを大胆に削除する必要がある。
- zoncoen氏:マイクロサービスでのインテグレーションテストは仕組み次第。ツール(シナリGo)やPRごとの専用環境デプロイなど、自動化で課題を乗り越えつつ、最終的に本番に近い結合状態を検証し、安心してデプロイできるのが理想。
「テストが増える=品質向上」では決してなく、“テストの可読性”と“本当に必要なカバレッジの確保”のバランスをいかに取るかが肝要です。
Goにおけるテストの実践的ノウハウを吸収しつつ、自チームの開発フローに合わせてテスト設計をブラッシュアップしてみてはいかがでしょうか。
Yardでは、テック領域に特化したスポット相談サービスを提供しています。
興味がある方は、初回の無料スポット相談をお申し込みください。
また、資料請求やお問い合わせもお待ちしております。テック領域の知見を獲得し、事業成長を一緒に実現していきましょう。