s4na's blog

s4naのテックブログ

ファーストペンギン

テスト駆動開発とは


本文について

昨日テスト駆動開発について学んだので、その内容をまとめてみました。
わからないところもあるので、その点については正直に「わからない旨」と記載しております。
テスト駆動開発」に入る前に、知っておいた方が良い「テスト」について書き、その後に「テスト駆動開発」について書いております。

誤字脱字ご指摘など連絡先

@s4na_penguin


テストとは

1. テストの最小単位

  • 不安
    • 正しく動かないことに対する不安の解消

2. 注意事項

  • テストの状態
    • Greenにするか消すかの二択
      • 放置してはいけない
  • テストのメンテナンスコスト
    • プロジェクト後半に発生する

3. 資産価値

  • 大きいテストの方が価値がある
    • 小さいテストは大きいテストをGreenにするためにある
  • 大きいテストの価値=小さいテストを積み上げていったもの

4. 分類

5. テストという言葉の持つ障害

  • 各々がテストという単語に対して、それぞれの立場で別の認識があるため、目的を明確にしていないと方向性にズレが出やすい
    • プロジェクトでテストという言葉は再定義しなければならない

6. テストの書き方

  • 2つの方針
    • 重複はあっても良い
      • テストコードはその部分だけ見ればある程度何をやってるかわかるコード,重複があってもいいから何をやってるかわかるノッペリとした書かれ方がいい
    • 重複はない方が良い
      • テストコードもコードはコード,テストコードにもプロダクトコードと同様にDRY原則が満たされなければならない
  • 重複があること
    • メリット
      • テストだけでやってることがわからないと、どこを探したら良いかわからないと大変
    • デメリット
      • 何か一つ修正したタイミングで、一気にRedが出ることがある
        • 修正にも時間がかかる

テスト駆動開発とは

1. 背景

  • 歴史
  • 用途
  • 支える環境
    • 軽快なテスト
    • 簡潔なテストコードでテストが実装・実行できる
    • 明快にテスト結果をみれる
    • 製品コードと開発環境の切り替えが容易

2. 概要

3. 目的

4. 目標(ゴール)

  • ゴール
    • 動作するきれいなコード
  • 「動作する」「きれいなコード」
    • 道は2つある
      • 「きれい」にしてから「動作する」
        • 伝統的なソフトウェア開発手法なこれを採用してきた
        • きれいな設計を作ってから実装する
        • 作り始めてから設計が複雑であるなど気づいたりする
        • 作ってみたら遅くて使い物にならないなどあったりする
      • 「動作する」にしてから「きれい」にする
        • TDDが採用している手法
        • 現在は予測可能性が低いので、「きれいな設計」を作ってからだと「動かしてみてからわからないこと」についていけない
          • できるできないではなく、正しく見ていかないといけない

5. テスト駆動開発は「恐れ」を突破するための技術

  • テストの罠
    • 堕落
      • 動いたからよしとしたい感情がある
    • 焦り
      • 他にも作らなきゃいけないものがあるから後回しになる
    • 恐れ
      • せっかく動くところまで来たのに、綺麗にするためにコードを書いたら動かなくならなくなるので、コードに手を入れたくない
      • 「動くコードに触れるな」みたいな言葉はここに由来する
  • テスト駆動開発は「テストが安心を担保してくれる」

6. 注意点

  • TDDのテストは品質を担保するわけではない
    • 結果的に品質は高まるが、目的ではない
  • テストのポイント
    • 特定の条件下で検証する
    • 本来はどうあるべきか?
    • 実際にどうなっているか?
  • リファクタリング
    • privateテストのテストは行わない

7. メリット・デメリット

メリット

デメリット

  • まだ不明

8. 構成

9. TDDでのテストの分類

  • 開発促進・設計行為
    • Developer Test
    • 目的
      • 開発者が開発者のために行うテスト
  • 進捗管理・機能要件
    • Customer Test
    • 目的
      • お客様から見て機能がどれくらいできあがっているか示す
  • 品質保証・非機能要件
    • QA Test
    • 目的
      • ソフトウェアの信頼性をあげるテスト

10. サイクル

  • 用語の説明

    • RED
      • どう動いて欲しいかという(失敗する)テストを書く
    • GREEN
      • テストを成功させる最低限のコードを書く
    • REFACTOR
  • 実際のサイクル

    • 次の目標を考える
    • その目標のテストを書く
    • そのテストを実行して失敗させる(Red)
    • 目的のコードを書く
    • テストを成功させる(Green)
    • テストが通るまでリファクタリングを行う(Refactor)
    • 繰り返す
  • アンチパターン(起こりがちな失敗)
    • リファクタリングのサイクルがなくなりがち
    • 理由
      • リファクタリングと名のついたタスクには呪いがかかる
        • 直近ではないように見える
          • ビジネス上の価値が感じられない
            • 技術者のエゴに見える
            • 技術者が非技術者に説明するのは難しい

11. リファクタリング

  • リファクタリングをいつまでやるか
    • 重複がなくなるまで
    • 不整合が解消されたという感情が得られた時
    • タイムボックス化

12. 実際のやり方

  • まずは実装を箇条書き
  • 優先順位を決める
  • 次にテストを書こうとする
    • テストの区切りを考えるのは難しい
      • どこまでやるのか?プリントできるかなど考えると難しい
    • 「明白な実装」といって、わざわざ細かく書く必要はない。
      • 実装が見えているなら書いてしまう
  • テストコードから書く
    • テストを書くには具体的に考えないといけない
      • テストを書くと掘り下げの甘さに気づける
    • 初めは重複しても良い
      • 重複はリファクタリングで消す
        • 重複数がいくつでアウトかは開発のルールに従う
          • だいたい2か3
  • テストは予想通り落ちるのが大事
    • そのためにはモックオブジェクト技法を使っても良い
      • モックオブジェクト技法
        • 偽物のオブジェクトをテストに使う技法
        • モックオブジェクト
          • テスト対象と協調動作するオブジェクトの偽物を使う
        • 利点
          • 開発前にテストができる
          • テストのテストができる

13. アンチパターン

  • テスト熱中症
    • 手段の目的化
    • GUI」「データベース」のテストが難しい
  • データベースのテスト
    • テストを動かす度にデータベースの中身が変わってしまって、Greenなのにテスト実行中はRedになったりする
      • テスト同士が暗黙の依存関係を持ってしまうことがある
    • ツール探しが大事
  • GUIのテスト
    • 問題点
      • 画面仕様は変わりやすいので資産価値が低い
      • 複雑になりやすくテストしにくい
      • ユーザビリティや画面のデザインはテストできないことも多々ある

14. How to

  • テストを書き始められなかったら
    • ゴール(検証)から書く
      • テストコードに慣れないうちや、何をテストしていいかわからなければ
  • テストメソッド
    • テストメソッドの中身の構成
      • 前準備
      • 実行
      • 検証
      • 後片付け(状況により必要)
  • テストコードの書き方
    • 個別の具体的なコードしか書かないと「仕様が読み取れない」
      • 名前から仕様が読み取れるようにしないといけない
        • 案1:テスト名は長くてもいいから仕様を示す長い名前にする
        • 案2:テストコードを入れ子にする
  • テストコードにバグがあったら
    • 実装側にやらせる
    • ミューテーションテスティング
    • テストコードのテストを一番最初にしとめる
      • 必ず成功する状態で実行する
  • 最小テストの方向性を正したい
    • 三角測量テスト
      • 最小テストを書いた後で、テストの方向性を正すために他のテストを書くこと
      • テスト毎にテストは1つ
      • 三角測量テストは「対称性の破れ」があるので後で消すようにする
    • 対称性の破れ
      • 三角測量のテストは消す
        • テストのテストは確認できた時点で消せるので
  • テストは消すのが難しい。消せるタイミングがあれば消す
  • 公布済みインタフェースのリファクタリング
    • 公布済み
      • publishedインタフェース
      • 他のチームや他の組織に使ってもらうためのインタフェース
    • 手順
      • 変更のアナウンス
      • 旧インタフェースが呼ばれたら新インタフェースにそのまま呼び出しを行うようにする
    • TDD
      • 大きいプロジェクトになると適応しにくくなる
        • 「先にクライアントとサーバの取り決めから始める」となるとpublishedインタフェースの中だけでしかTDDで自由に開発できなくなる

参考