Skip to content

Instantly share code, notes, and snippets.

@smeghead
Last active October 1, 2025 06:28
Show Gist options
  • Save smeghead/7ef4d3c22371088a729c96f96611c716 to your computer and use it in GitHub Desktop.
Save smeghead/7ef4d3c22371088a729c96f96611c716 to your computer and use it in GitHub Desktop.
テスト駆動開発(Test-Driven Development)入門

テスト駆動開発(Test-Driven Development)入門

Note: 社内のTDDを知らない人向けに、TDDの基本説明とデモを行なう機会があり、その時に使った資料です。

テスト駆動開発


動作するきれいなコード

テスト駆動開発(TDD)では、「動作するきれいなコード」を維持しながら機能追加を行なうことを目指します。

  1. 今から実装してようとしている小さい問題について、TODOリストを作成する。
  2. 一番取り掛かりやすいTODOを選択し、テストを行なうメソッドを追加する。
  3. テストを実行して、テスト結果が失敗することを確認する。🔴
  4. 考えられる一番簡単な実装を行なう。
  5. テストを実行して、テスト結果が成功することを確認する。🟢
  6. 実装に改善できる箇所があればリファクタリングを行なう。
  7. テストを実行して、テスト結果が成功することを確認する。🟢

これをループで回しながらTODOリストを消化していきます。 このループは、「レッド → グリーン → リファクタリング」と表現されます。 実装を進めていくと、要件が明確になることで、追加のTODOが出てきます。 追加のTODOは、TDDのループの実践からの貴重なフィードバックなので、TODOリストに追加します。 レッドの状態が長く続いてしまう場合は、TODOの粒度が大きすぎることが原因かもしれません。 それがストレスになるようであれば、TODOを更に分割できないか検討してください。


レッド → グリーン → リファクタリングのループの利点

このループに忠実に従うことは、一見まどろっこしいと思う人もいるかもしれませんが、多くの利点があります。

TODOリストの作成

TODOリストを作成することは、今から実装する処理についての設計を行なうことになります。 また、TODOリストはテストメソッドに反映されることになるため、動作する設計書の役割を担うことができます。

開発者のストレス軽減

開発者は、大量の項目の処理や複雑な処理を実装する場合、既存の機能を壊すことなく実装するために、大きなストレスを感じながら作業することになります。 レッド → グリーン → リファクタリングのループでは、TODOリストの一つのTODOに専念して行なうため、ストレスが少なくなります。 更に、レッド、グリーンを小まめに確認しながら進めるため、グリーンの状態の時に常に「希望通りに動作する」ということに自信を持てることもストレスを軽減します。


実装後のテストコードの価値

テストコード: テストが記載されたファイル プロダクションコード: 本番環境で動作する実装が記述されたファイル

テストコードは、初期の実装時だけでなく、長い間様々な用途で役に立ちます。

実装の仕様やコンポーネントの利用方法の資料としての価値

TDDで開発されたテストコードは、開発時のTODOリストを反映したものとなっているので、どのように使用されることを想定しているか。というのを確認するときに参考になります。

仕様変更があった場合のガードレールとしての価値

TDDで作成した既存のコードは、テストコードが残っているため、すぐTDDループで開発を行なうことができます。 具体的には、まず仕様変更に従ってテストコードを修正し、レッド🔴を確認してから、プロダクションコードを修正して🟢を確認します。 テストコードが継続的に利用可能であることが、既存の機能を壊さずに仕様変更を行うためのガードレールとなります。

不具合調査時に、実装者の意図を示す資料としての価値

不具合調査時に、想定外の使われ方をしたために発生したのか、実装が間違っていたのかなど原因の調査時に、テストコードは役に立つ情報となります。

リグレッションテスト(回帰テスト)としての価値

全てのテストを実行してグリーンを保っているのであれば、実装時に想定していた通りの動作が現在も機能していることを確認できます。 デプロイ前にリグレッションテストとして実行することで、既存の機能を壊していないかどうかを確認できると安心してデプロイできるようになります。(TDDのテストだけで100%安心とはなりませんが、不安を減らすことができます)


TDD 実践のコツ

手順はわかっても、上手にTDDループを回し、ストレスなく継続的に運用していくのは、なかなか難しいというのも事実です。

コンポーネント設計

テスト対象のコンポーネントの特定は、最初のかなり重要な設計の勘所です。

副作用

どういう要素が絡むとテストを書くのが難しくなるかを理解する必要があります。

入出力の利用

ユーザー入力、ファイル入出力、データベースクエリ、API呼び出しなどを内包しているコンポーネントは、テストを書くのが難しくなります。

ランダムな要素に依存する

ランダムな数値を取得する関数などを呼び出すメソッドは、テスト結果もランダムになるため、テストを書き難くします。

  • rand 関数(乱数を生成する)の呼び出し
  • 現在時刻の取得

副作用の無いコンポーネントを設計することができれば、テストを書くのは非常に簡単になります。


TDDデモ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment