テスト駆動JavaScriptの第2章をメモ

Node塾 講義その6に行くのでメモった


Node塾で下記の読書会をする。

テスト駆動JavaScript

テスト駆動JavaScript


以下は第2章を抜粋したメモ。これを読んで頂ければわかるがテスト駆動JavaScriptJavaScriptでTDDをするにはどうすればいいかだけに答えるものではなく、TDD未経験者でもTDDとは何なのか?どうやってTDDを身に付けるのかを記載した本になっている。興味があれば買うといいよ。そしてNode塾に参加すればいいと思いますよ。

第2章 テスト駆動開発プロセス

  • テストから仕様へ
  • テストは本番コードを書く前に、仕様として書かれる
    • 利点
      • テストがしやすくなる
      • インターフェースがクリーンになる
      • デベロッパーが自信を持てるようになる
  • 開発の上下をひっくり返す
    • テスト駆動開発では、問題を解決するためにどのようなコードが必要なのかを考えるのではなく、まず目標を定義するところから始める
    • 単体テストはどのような動作がサポートされ、計算にはいっているかを示す仕様書になる。
  • テスト駆動開発における設計
    • TDDは、何もないところから優れた設計を自動的に生み出すわけではなく、作業の進展とともに設計を進化させやすくするのである
    • TDDは、単体テストに強く依存しているため、他の部分から切り離して単独のコンポーネントに力を注ぐ開発スタイルになる。
      • そのため、コードの疎結合を保ち、単一責任の原則を守り、不必要にコードが水ぶくれすることを防ぐ
    • テスト駆動開発のもとでは、設計のことをじっくりと考えないわけにはいかなくなる
      • いつでもまず単体テストという形で妥当なユースケースを組み立てるところから仕事を始める
      • 単体テストを書くためには、思考実験が必要
        • 解決しようとしている問題を記述しなければならない
        • それが終わらなければ、実際にコーディングをスタートさせる事ができない
      • TDDはソリューションを提供する前に、結果について考えなければならない
  • プロセス
    • 4つのステップ
      • テストを書く。
      • テストを実施する。新しいテストが不合格になるのを確認する。
      • テストに合格するようにコードを書く。
      • リファクタリングして重複を取り除く。
    • テストを書くことこそが設計になる
    • テストを書くということは
    • TDDのイテレーション
      • 今どの段階にいるのかを意識し、よく考える事
    • TODOリスト
      • 例)引数が足りないときはエラーを投げる
  • Step1.テストを書く
    • 優れたテストは短く
    • 関数/メソッドの単一のふるまいだけを対象に
      • 1つのふるまいだけのテストを作るための目安
        • できる限りすくないコードでテストを不合格にすることを考えるとよい
        • 新しいテストは、すでに動作することがわかっているアサーションを重複させないように
    • 単体テスト
      • 既知の入力を渡し、
      • 出力が想定通りになっていることを
      • アサートして
      • コードが想定通りに動くことをチェックする
    • ※入力
      • 関数の引数だけではない
      • グローバルスコープ
      • 特定のオブジェクトが特定の状態になっていること
      • など
    • ※出力
      • 戻り値だけではなく
      • グローバルスコープや
      • 所属オブジェクトの変化も含む
  • Step2.テストが不合格になるのを確認する
    • 合格するコードを書く前にテストを実行する
      • 理由
        • コードの現在の状態について、私たちの理論の正しさを確かめること
        • テストがどのように不合格になるのかについて明確に想定できていなければならない
        • 単体テストにもバグがある)
  • Step3.テストを合格させる
    • テスト駆動開発プロセスにはあるリズムがあり、作られたソリューションがその時点では完璧でなくても、イテレーションを完結させたというパワーを過小評価すべきではない
    • 自明の実装
    • テストを合格させるために必要なだけのコードを追加する
    • コードを追加させるということはふるまいを追加すること
      • 追加されたふるまいは、追加された要件によって表現されなければならない
      • 明確な要件を背後に持たないようなコードがあるとすれば、それは水ぶくれに過ぎない
    • YAGNI「you ain't gonna need it」
      • それが必要になることはない
      • 必要になるまで機能を追加してはならないという原則
      • いつかいいことをしてくれるという前提のもとでコードを追加すると、その部分の必要性を具体的に示すユースケースがないのに、コードベースに水ぶくれの無駄なコードを追加することになる
      • YAGNI違反の一つは、メソッド引数を過度に柔軟にすること
      • 追加したコードの妥当な使い方を具体的に示すテストが作れるようになるまでは、そのコードを追加してはならない
    • 足場
      • ハードコードでもかまわない
      • 何も手がかりがないのに一般的なソリューションを探さなければ先に進めないようにすると、時間を使いすぎてしまう
      • 開発ペースを保つために、中間的なソリューションとしてハードコードを認めている
  • Step4.重複を取り除くためにリファクタリングする
    • 重複を取り除き、設計を改良する
    • ルールはテストはグリーンのまま維持するということ
    • 同時に複数の作業をしてはならない
    • リファクタリングとは、インターフェースを変えないようにしながら実装を書き換えることだ
    • 重複は、テストでも本番コードと同じように望ましくない
      • テストとシステムが密結合になりすぎていることを表している
      • 密結合になりすぎている場合は、(ヘルパー)メソッドの抽出などのリファクタリング技法を使って重複を取り除く
      • テストもコードなので、メンテナンスが必要
  • シャンプー、リンスの繰り返し
    • 1歩の大きさを大きくしたくなるかもしれないが、ひんぱんにフィードバックをもらえる状態に保つために、サイクルは短くした方がよい
    • 一歩を大きくしすぎると、追跡しにくいバグや手作業のデバッグなど、このプロセスで避けようとしている多くの問題に直面することになり、このプロセスを採用した意味がなくなる
  • テスト駆動開発を円滑に進めるために
    • 自動テストを実行すること
      • ファイルが保存されるたびにテストが実行されるようにするということ
      • テストの実行は環境のほうの仕事
  • テスト駆動開発の利点
    • 動作するコードが手に入る
    • 単一責任の原則を尊重できる
    • 意識的な開発が強制される
      • ふるまいを記述するテストを書くことから始まるので、書く前にコードについて考えなければならなくなる
      • 解こうとする前に問題について考えると、しっかりとしたソリューションを作れる可能性が大幅に上がる
      • 代表的なユースケースを通じて各機能を記述することから始めると
      • コードを小さく保てることが多い
      • コードの実際の使用例から書き始めるので誰も必要としない機能を導入する可能性は下がる。YAGNI原則
    • 生産性が向上する
      • 以前よりもテスト、コードの入力のためにエディタで使う時間は少し長くなるだろう
      • しかし、ブラウザでF5キーをたたきまくる時間は大幅に短縮される
      • テストによってカバーされているコード
      • リファクタリングはもう怖くなくなるだろう
      • ストレスは減り、以前よりも幸せな気分で素早く仕事がこなせるようになる
  • まとめ
    • イテレーション
      • 新しいふるまいをテストに書き
      • テストを実行して想定通りに不合格になる
      • テストに合格するために必要な最小限のコードを書き
      • 最後に重複を取り除き
      • 設計を改良するために、積極的にリファクタリングをかける