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
テスト駆動開発(TDD)入門
Search
ymgc
January 10, 2025
Programming
0
15
テスト駆動開発(TDD)入門
ymgc
January 10, 2025
Tweet
Share
More Decks by ymgc
See All by ymgc
LLMのテスト時計算最適化に関する研究
__ymgc__
0
5
AI に特化した品質特性のテスト
__ymgc__
1
28
AIを活用したソフトウェアテスト技術 - ISTQB Foundation Level - AI Testing (CT-AI)
__ymgc__
1
22
Machines of Loving Grace - AIはどのように世界をより良く変えるか -
__ymgc__
1
48
ファシリテーションの技術
__ymgc__
2
49
(論文読み)BigCodeBench: 多様な関数呼び出しと複雑な指示を用いたコード生成のベンチマーキング
__ymgc__
1
42
(論文読み)Very Large-Scale Multi-Agent Simulation in AgentScope
__ymgc__
1
39
7 POWERS
__ymgc__
1
32
自己組織化系のベイズ力学
__ymgc__
1
48
Other Decks in Programming
See All in Programming
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
140
テストケースの名前はどうつけるべきか?
orgachem
PRO
1
180
ゆるやかにgolangci-lintのルールを強くする / Kyoto.go #56
utgwkk
2
800
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
1.3k
バグを見つけた?それAppleに直してもらおう!
uetyo
0
210
PSR-15 はあなたのための ものではない? - phpcon2024
myamagishi
0
360
AppRouterを用いた大規模サービス開発におけるディレクトリ構成の変遷と問題点
eiganken
1
410
React 19でお手軽にCSS-in-JSを自作する
yukukotani
5
540
毎日13時間もかかるバッチ処理をたった3日で60%短縮するためにやったこと
sho_ssk_
1
500
AWSのLambdaで PHPを動かす選択肢
rinchoku
2
360
なまけものオバケたち -PHP 8.4 に入った新機能の紹介-
tanakahisateru
1
140
Jaspr Dart Web Framework 박제창 @Devfest 2024
itsmedreamwalker
0
140
Featured
See All Featured
GraphQLとの向き合い方2022年版
quramy
44
13k
KATA
mclloyd
29
14k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
171
50k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
230
52k
Statistics for Hackers
jakevdp
797
220k
Designing for Performance
lara
604
68k
The World Runs on Bad Software
bkeepers
PRO
66
11k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.1k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
Transcript
テスト駆動開発(TDD) 入門 動作する綺麗なコードへの実践的アプローチ 1
想定読者 プログラミング経験のある開発者 ▶ テスト自動化に興味がある方 ▶ コードの品質向上を目指している方 ▶ アジャイル開発手法を学びたい方 ▶ 2
目次 1. テスト駆動開発(TDD) の本質 2. テスト駆動開発のサイクル 3. 問題の分割方法 4. テストコード作成のコツ
5. 実装の3 つのアプローチ 6. テストコードのメンテナンス性 3
本スライドのゴール TDD の基本概念と実践方法の理解 ▶ テストファーストの考え方の習得 ▶ 実装パターンの使い分けの習得 ▶ 保守性の高いテストコード作成スキルの獲得 ▶
4
用語 TDD: Test-Driven Development (テスト駆動開発) ▶ レッド: テストが失敗している状態 ▶ グリーン:
テストが成功している状態 ▶ リファクタリング: 外部の振る舞いを変えずに内部構造を改善すること ▶ アサーション: テストにおける期待値の検証 ▶ DRY: Don't Repeat Yourself (重複を避けること) ▶ テストファースト: 実装前にテストを書く方法 ▶ モック: テスト用の代用オブジェクト ▶ カバレッジ: テストによるコードの網羅率 ▶ 5
1. テスト駆動開発(TDD) の本質 6
TDD とは Kent Beck 氏が考案した開発手法 ▶ 「動作する綺麗なコード」を目指す ▶ 通常のプログラマーが着実に前進するための技法 ▶
7
TDD の特徴 天才プログラマーのためではない ▶ 常に設計し続ける(設計をしないという誤解がある) ▶ 分割統治アプローチを採用 ▶ 8
理想のコードへの2 段階アプローチ 1. まず「動作するコード」を作る たとえ汚くても動作優先 - スピード重視 - 2. その後「綺麗なコード」に改善
動作を保ったまま - リファクタリングによる品質向上 - 9
重要な考え方 一気に理想のコードは書けない ▶ 小さなステップを積み重ねる ▶ フィードバックを常に活用 ▶ テストを通じて設計を改善 ▶ 10
2. テスト駆動開発のサイクル 11
レッド・グリーン・リファクタリング 3 つのフェーズを繰り返す基本サイクル ▶ 各フェーズには明確な役割がある ▶ 7 つのステップで具体化される ▶ 12
開発の7 ステップ 1. 目標設定と簡単な設計 2. 次の目標選択 3. テストを書く(テストファースト) 4. テスト実行で失敗確認(レッド)
5. 実装を行う 6. テストの成功確認(グリーン) 7. リファクタリング 13
開発の7 ステップ 1. 目標設定と簡単な設計 現在の理解をテキストファイルに記録 ▶ TODO リストの作成(過剰気味に) ▶ 実装前に全体像を把握
▶ 2. 次の目標選択 テスト容易性が高いものを優先 ▶ 重要度との両立を考慮 ▶ 14
開発の7 ステップ ( 続き) 3. テストを書く(テストファースト) 利用者視点でテスト作成 ▶ 実装前にテストを書く ▶
API の使いやすさを検証 ▶ 4. テスト実行で失敗確認(レッド) 意図的な失敗 ▶ 予想通りの失敗を確認 ▶ 15
開発の7 ステップ ( 続き) 5. 実装を行う テスト成功が最優先 ▶ 最短距離でグリーンを目指す ▶
コード品質は二の次 ▶ 6. テストの成功確認(グリーン) 全テストの成功を確認 ▶ 16
開発の7 ステップ ( 続き) 7. リファクタリング テスト成功を維持したまま改善 ▶ プロダクトコード/ テストコード両方が対象
▶ 5-10 分程度で区切りをつける ▶ TODO リストに戻る ▶ 17
サイクルの特徴 各ステップが小さい ▶ フィードバックが早い ▶ 常に動作する状態を維持 ▶ 品質と速度のバランスを取る ▶ 設計が徐々に改善される
▶ 18
3. 問題の分割方法 19
テスト容易性と重要度による分類 2 つの軸で問題を整理 ▶ 優先順位付けの指針となる ▶ 実装の順序を決定する基準 ▶ 20
テスト容易性の3 要素 観測の容易さ (Observability) 制御の容易さ (Controllability) 十分な小ささ (Size) テストから結果が見えやすいか ▶
出力が明確か ▶ 入力値の設定が容易か ▶ テスト実行の制御が可能か ▶ テストの範囲が適切か ▶ 一度に検証する機能が限定的か ▶ 21
I/O 処理の分離 プリント処理などのI/O 処理 ▶ テスト容易性が低い - 本質的なロジックから分離する - 変換処理として再定義
- 分離の利点 ▶ テストが書きやすくなる - ロジックが明確になる - 保守性が向上する - 22
正常系・準正常系の区別 正常系から着手 ▶ 基本的な機能を先に実装 - 具体的な値から始める - 例:1, 2 などの単純なケース
- 徐々に抽象化 ▶ パターンを見出す - 一般化を進める - リファクタリングで改善 - 23
重複への対応 2 つのアプローチ 2 アウト派 ▶ 2 箇所の重複で即対応 - 早めの統合を重視
- リスク:早すぎる抽象化 - 3 アウト派 ▶ 3 箇所の重複まで待つ - パターンの確認を重視 - リスク:重複の放置 - チームで方針を統一することが重要 ▶ 24
4. テストコード作成のコツ 25
下から上への記述順序 1. 検証(Assert) から開始 ▶ テストのゴールを明確化 - 期待値を最初に定義 - テストの目的を明確に
- 2. 実行(Act) を記述 ▶ テスト対象の処理を実行 - 必要最小限の操作 - 3. 準備(Arrange) を最後に ▶ 必要なデータを用意 - テストの前提条件を整備 - 26
1 テスト1 アサーションの原則 アサーションルーレットの問題点 例外的なケース テスト失敗時のデバッグが困難 ▶ テストの意図が不明確 ▶ 保守性の低下
▶ End-to-End テスト ▶ 実行コストが高いテスト ▶ 論理的に関連する複数の検証 ▶ 27
テストメソッドの命名規則 基本方針 仕様レベルの言葉を使用 ▶ 日本語での記述を推奨 ▶ テストが動作するドキュメントに ▶ 28
重要な注意点 テスト間の独立性を保持 ▶ 副作用を避ける ▶ 可読性を維持 ▶ 29
5. 実装の3 つのアプローチ 30
1. 仮実装アプローチ (Fake It) 2. 三角測量アプローチ (Triangulation) 3. 明白な実装アプローチ (Obvious
Implementation) 31
1. 仮実装アプローチ (Fake It) 特徴 メリット デメリット 最も単純な実装(例:return 1 )
▶ テストを最短で通す ▶ 一時的な実装 ▶ テストコードの検証が可能 ▶ 設計に集中できる ▶ 素早くグリーンに到達 ▶ 後で書き直しが必要 ▶ 技術的負債になる可能性 ▶ 32
2. 三角測量アプローチ (Triangulation) 特徴 メリット デメリット 複数のテストケースを用意 ▶ 具体例を増やしながら実装を一般化 ▶
段階的な実装の改善 ▶ 実装の方向性が不明確な場合に有効 ▶ 段階的に理解を深められる ▶ 過剰な一般化を避けられる ▶ 開発速度が遅くなる ▶ テストケースが増える ▶ 33
3. 明白な実装アプローチ (Obvious Implementation) 特徴 メリット デメリット 一気に本実装まで進める ▶ テストを書いてすぐに実装
▶ 最短距離での実装 ▶ 最も効率的 ▶ 開発速度が速い ▶ 余分なステップを省ける ▶ 経験が必要 ▶ 見通しを誤る可能性 ▶ リスクが高い ▶ 34
アプローチの使い分け 状況に応じた選択 使い分けの例 問題の理解度 ▶ 技術的な確信度 ▶ 時間的な制約 ▶ 1.
新しい概念の実装 → 仮実装 2. 複雑なロジック → 三角測量 3. 既知のパターン → 明白な実装 35
6. テストコードのメンテナンス性 36
動作するドキュメントとしてのテスト 構造化の重要性 TODO リストの構造をテストコードに反映 ▶ ネストしたクラス構造の活用 ▶ 仕様の階層構造を表現 ▶ 37
メンテナンス性向上のための施策 重複の適切な除去 テストの独立性確保 共通セットアップコードの抽出 ▶ 不要なテストケースの削除 ▶ DRY 原則の適用 ▶
テスト順序への依存を避ける ▶ 並列実行可能な設計 ▶ 副作用の排除 ▶ 38
テストコード整理のタイミング ベストプラクティス 実装直後の整理 ▶ 意図が記憶に新しい - 仕様理解が明確 - 定期的なリファクタリング ▶
コードレビュー時 - 新機能追加時 - バグ修正時 - 39
長期的なメンテナンス考慮事項 チーム内での共有 継続的な改善 命名規則の統一 ▶ 構造化ルールの確立 ▶ レビュー基準の明確化 ▶ 定期的な見直し
▶ 不要コードの削除 ▶ テストカバレッジの維持 ▶ 40
まとめ TDD の3 つの重要なスキル 次のステップ 1. 問題の分割力 2. 実装アプローチの使い分け 3.
テストコードの構造化能力 小さな問題での練習 ▶ チームでの実践 ▶ 継続的な改善 ▶ 41