僕の考えるテストファースト開発技法

Utilitys

はじめに

この記事では、ウォーターフォール開発を前提に、各工程でどのようにテストファースト的に振る舞うかを整理します。


テストファーストは実装だけの話じゃない

Kent Beck のTDD(Test Driven Development)は「Red → Green → Refactor」で有名ですが、本質は「動く前に、どうあるべきかを定める」ことです。

つまりこの考え方は、要件定義・基本設計・詳細設計といった上流工程にも応用できます。


各工程とテストの対応・考え方

要件定義 × システムテスト

  • 目的: ユーザーがやりたいこと、業務的な期待値を整理する
  • テストファースト的アプローチ:
    • 利用シナリオごとの正常系/異常系を洗い出す
    • 最終的な「動作確認のゴール」を明文化する
  • 例:
    • ユーザー登録で重複エラーになる条件、エラーメッセージの内容などを仕様として明記

基本設計 × 結合テスト

  • 目的: モジュール間のやりとり、画面とDBの接続点、APIの流れを定義する
  • テストファースト的アプローチ:
    • どのモジュールが何を受け取り、何を返すかを定義
    • 連携パターンと異常ケースを網羅的に設計
  • 例:
    • 「CSV取込 → バリデーション → DB登録」の流れの中で、途中失敗時のロールバックやエラー通知を明示する

詳細設計 × 単体テスト

  • 目的: 各クラス・関数・メソッドの仕様を定義
  • テストファースト的アプローチ:
    • 入力値と出力値のあらゆる組み合わせを考慮
    • 境界値、異常値、NULLなどの振る舞いを具体化
  • 例:
    • 金額計算処理の丸め誤差、0円入力、マイナス値の時の期待動作など

テストファースト思考の共通原則

  • 各工程では「その工程の目的に応じた期待値・網羅性」を重視する
  • 実装に入る前に、「こうなっていてほしい」を明確にする
  • 記述がコードになっていなくても、頭の中にテストの視点があることが重要

メリット・デメリット

メリット

項目内容
要件漏れ防止テスト視点でパターンを考えるため、漏れが減る
手戻り減少実装後に「想定外のケース」に気づくリスクが下がる
レビューがしやすい期待値ベースで設計やコードをチェックできる
チーム共通認識テスト観点を通じて、仕様認識のずれを防げる

デメリット

項目内容
工数が見えづらい「テスト設計思考」は明文化されにくい
重箱の隅になりがち異常系ばかりに気を取られてしまうことも
経験が必要網羅性の判断には経験が必要で、属人化しやすい

まとめ

テストファーストって、なんか「テストコードを先に書こうぜ」って話に見えがちだけど、僕としてはもっと広い意味で捉えてます。

実装に入る前に「こう動くべき」って期待値とかパターンをちゃんと考えとこうよっていうスタンスで
それが要件定義だろうが、基本設計だろうが、どのフェーズでも大事な姿勢だと考えました。

ただ、全部の工程で全員がそれを意識する必要があるかって言うと、別にそうでもなくて。
リーダーとかレビュアーがそういう視点を持って、レビューや方針決めのときにちゃんと網羅性とか「抜けてるとこない?」って見てあげれば、それで十分機能するんじゃないかなと。

結局のところ、「事前にちゃんと考える」というだけでプロジェクトの精度はかなり上がるし、
それがテストファーストの本質なんじゃない?と、この記事を作りながら考えてました。