Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
駆け足で Google から学ぶテスト設計の指針
Search
ryounasso
August 25, 2025
Programming
0
110
駆け足で Google から学ぶテスト設計の指針
ryounasso
August 25, 2025
Tweet
Share
More Decks by ryounasso
See All by ryounasso
明日から始めるリファクタリング
ryounasso
0
110
React inside basics: learn from “build own react"
ryounasso
0
140
抽象データ型について学んだ
ryounasso
0
260
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
3.1k
Clean Architecture by TypeScript & NestJS
ryounasso
0
960
Fast API を用いた Web API の開発
ryounasso
0
540
テストゼロの個人開発プロジェクトにテストを導入した話
ryounasso
0
410
簡易 DI コンテナを作って DI コンテナを知る
ryounasso
1
1.3k
TypeScript_コンパイラの内側に片足を入れる
ryounasso
3
790
Other Decks in Programming
See All in Programming
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
150
CSC509 Lecture 02
javiergs
PRO
0
400
10年もののAPIサーバーにおけるCI/CDの改善の奮闘
mbook
0
750
麻雀点数計算問題生成タスクから学ぶ Single Agentの限界と Agentic Workflowの底力
po3rin
5
2.1k
dynamic!
moro
9
6.1k
WebエンジニアがSwiftをブラウザで動かすプレイグラウンドを作ってみた
ohmori_yusuke
0
170
SpecKitでどこまでできる? コストはどれくらい?
leveragestech
0
490
『毎日の移動』を支えるGoバックエンド内製開発
yutautsugi
2
150
猫と暮らすネットワークカメラ生活🐈 ~Vision frameworkでペットを愛でよう~ / iOSDC Japan 2025
yutailang0119
0
220
止められない医療アプリ、そっと Swift 6 へ
medley
1
110
エンジニアとして高みを目指す、 利益を生み出す設計の考え方 / design-for-profit
minodriven
23
12k
Web Components で実現する Hotwire とフロントエンドフレームワークの橋渡し / Bridging with Web Components
da1chi
3
1.6k
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.1k
YesSQL, Process and Tooling at Scale
rocio
173
14k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
The Language of Interfaces
destraynor
162
25k
How to train your dragon (web standard)
notwaldorf
96
6.3k
Embracing the Ebb and Flow
colly
88
4.8k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
GraphQLとの向き合い方2022年版
quramy
49
14k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
32
2.2k
Writing Fast Ruby
sferik
629
62k
Transcript
駆け足で Google から学ぶテスト設計の指針
「Googleのソフトウェアエンジニアリング」本の 11 ~ 13 章を読み、テスト・ユニット テストに関する重要な点を学んだ。 11章:テスト概観 12章: ユニットテスト 13章:
テストダブル
学んだこと テスト文化とその意義 テストの分類と設計方針 曖昧さをなくすテストの分類方法 理想のテストピラミッド 保守性の高いユニットテストを書くためのプラクティス テストダブルの活用方法 抽象データ型との繋がり
テスト文化とその意義 テストを 開発プロセスの中心に据えた自動テスト文化 がもたらすメリット デバッグの減少 変更への信頼の増大 ドキュメンテーションの改善 レビューワーの負荷軽減 良い設計につながる 高速で高品質なリリース
開発プロセスの中心の据えた自動テスト文化 を成り立たせる重要な要素 エンジニアが日常的にテストを回す仕組み 破綻したテストをすぐに修正する文化
テストの分類と設計方針
曖昧さをなくすテストの分類方法 「ユニットテスト」とはどんなテストを指すのか、解釈に幅がある。 → 規模 (実行に要するリソース) で小・中・大、範囲 (検証している特定のコードパス) でユニット・インテグレーション・E2Eに分類可能 この規模の分類と範囲の分類を掛け合わせることで 3×3
のマトリクスが得られる。 小テスト 中テスト 大テスト 小範囲 中範囲 大範囲 これでテストの分類に関する曖昧さを減らした議論が可能に
理想のテストピラミッド Google では、 ”エンジニアリング生産性” と “製品の信頼性“ の観点から、テストスイート の設計において以下の指針がある 引用: Google
ソフトウェアエンジニアリング
ユニットテスト中心の構成がもたらすメリット 1テスト当たりの実行時間が短く、フィードバックサイクルが高速 素早くかけるため、テストカバレッジが高水準になりやすい 各テストの内容・目的が単純で、失敗した際に間違っていた理由を理解しやすい
保守性の高いユニットテストを書くためのプラクティス 保守性の高いユニットテストをかけなかった場合、エンジニアの生産性が低下してし まう。 この保守性の高いユニットテストを書くために重要なポイント 脆いテストを防ぐ 明確なテストを書く DAMP なテストコードを目指す
脆いテストを防ぐ 脆いテストとは 実際のバグを全く持ち込んでいない無害かつ無関係な変更に反応して壊れるテスト 理想のテストとは テスト対象システムの要件が変化しない限り、書かれた後は二度と変更が必要ないテ スト この理想のテストを書くためのプラクティスは 公開 API に対するテストを書く
ことと ステートテストを書く こと。
公開 API に対するテストを書く 公開 API に対するテストを書くとは、つまり テスト対象システムのユーザーが呼び出 すのと同じ方法でシステムを呼び出すテストを書く こと。 適切な
公開 API を定義することが重要だが、明確な観点があるわけではなさそう。 (書籍には、経験に基づくユニットに適切な範囲を定義し、それにより公開 API とみな されるべきもの定義する方法が紹介されていた)
ステートテストを書く テスト対象システムが期待通りの挙動を行うか検証する2つの方法 ステートテスト システムのメソッドを呼び出した後に結果が何 (what) であるかを見る インタラクションテスト どのように (how) システムがその結果に到達しかたをチェックする
通常、how をチェックするためにシステムの内部的な実装の詳細に依存するインタラ クションテストは脆くなりがち。
明確なテストを書く 明確なテストとは、その存在目的と失敗理由が、失敗の原因を究明するエンジニアか ら見て明確となるテスト 明確なテストを書くプラクティスは以下の通り テストは完全かつ簡潔にする テストの本体部分に、重要でない情報や紛らわしい情報は全く含まずに、テ ストを理解するのに必要な情報を全部含むテスト メソッドではなく、挙動をテストする テストにロジックを入れない 明確な失敗メッセージを書く
DAMP なテストコードを目指す DAMP (Descriptive And Meaningful Phrases) とは、説明的かつ意味がわかりやすい言い 回しがされていること。 少々の重複は、それがテストを単純かつ明確なものにする限り問題ない。
逆に、共有する価値があるコードは以下の通り 共有値 初期設定の共有 ヘルパーメソッドと検証メソッドの共有 テストインフラストラクチャーを定義 例: JUnits
テストダブルの活用方法 テストダブルのメリット コードの複雑性が増した際にユニットテストを書きやすくする 本物の実装よりも軽量なため、迅速に実行可能な小テストを書きやすくなる テストダブルのデメリット テストダブルを利用するには、コードベースがテスト可能なように設計されている 必要があり、設計コストがかかる (テスト可能性) テストダブルを不適切に使用すると、テストが脆く、複雑になる可能性がある (応
用性) テストダブルの挙動を本物の実装とかなり似せておかないと、実際にテストした い内容が観れるとは限らない (忠実性)
テストダブルの種類と特徴 フェイキング 本物の実装より高速な、本物の実装同様に振る舞うシステム 本物と同じAPI契約を守ることが必須 スタビング 特定の戻り値や例外を返すだけの実装 複雑なシナリオやエラーケースを手軽に再現できる 多用すると、テストが不明確になる & 脆くなる
モック 関数がどのように呼ばれるかを、その関数の実装を実際に呼び出すことなく 検証する方法 内部実装の詳細に依存しがちで、最も脆くなりやすい
本物の依存かテストダブルを使うかの判断基準 観点 実行時間 本物が遅くてフィードバックが阻害される場合はテストダブルを検討 決定性 外部サービスへの依存でたびたび失敗するならテストダブルに置換 依存関係の複雑さ 本物を組み込むために膨大なセットアップが必要ならフェイク優先 方針 まず本物の依存を使い、遅い・不安定になったらフェイク→スタブ→モックと段階的
に導入
抽象データ型との繋がり 以前の関ジャバで 抽象データ型 に関してお話しさせていただいた。 この考え方に則ってテスト対象を設計することで、良いテストが書きやすくなると感 じた。
抽象データ型に基づいた公開 API を用いることで、脆いテストが書きづらくなる 公開 API に依存することが必ず実装の詳細に依存しないとは限らない 抽象データ型に基づいてクラスを設計することで、公開 API が実装の詳細を 外部に露出しなくなり、脆いテストが書きづらくなる
検査すべき挙動 = 公理と捉えることができて、ユニットテストで何を担保するべ きかが明確になる メソッドではなく挙動をテストするべし、の挙動が公理から見えてくる 契約が明確になることでフェイクで何を実装するべきかがわかりやすくなる 事前条件・事後条件を記述するため
まとめ 1. 自動テストを大事にする文化がエンジニアの生産性を向上させる 2. 良い自動テストを書くための指針を理解する 3. 良いテストを書くためには、良い設計が必要
参考文献 Google ソフトウェアエンジニアリング(11–13章) オブジェクト指向入門 第2版 原則・コンセプト