- Contents -
前回記事: テスト駆動開発の本読んだ! の後編です。
テストファースト
テストは実装コードを書く前の段階で書くべし。
テストするために実装を改修する必要もあるので、
実装し終わった機能のテストを後から書くことは難しい。
ストレスの因果ループで説明したように、
テストがまずある状態にしておかないと、
どんどん時間がなくなるループに陥る。
まずはテストコードを書き、因果ループを逆回転させる。
あるべき仕様から実装をおこす事にもなる。
TDDは強要しない
他の人の働き方を強制するのは難しい。
TDDを実践する事により、テストが書かれたコードは問題が少ない事、設計が良い事を皆に認知してもらおう。
仕様の確認も、テストコードを元に共有すれば、
有用性が伝わりやすい。
対象のクラスがどういった挙動をするのか、
テストコードを通して表現する事ができる。
回帰テスト
不具合が確認された時、再現するテストケースを書こう。
失敗するテストを書いてから、不具合を修正。
そのテストが無事通るようになったら、不具合は修正されたと判断できる。
回帰テストを残しておくことで、
リグレッションがおこらず品質を担保できる。
テスト技法
テストするうえで、知っておきたい手法。
Mock Object
テスト用に偽装させたクラスを作成して、偽装オブジェクトとして使う。
特定クラスや、インターフェイスのサブクラスを作成する事になる。
テスト対象クラスが、他クラスに依存する場合、
しかも、そのインスタンス化またはテスト実行時には都合が悪い挙動をする場合に、代替えとしてとして用意する。
例えば、DB接続するようなクラスなど。
以降のテストパターンでも、テスト用のメソッド処理を実装したりなど、テストするうえで必須の手法。
※モック、スタブの違い
モックもスタブも、元オブジェクトに取って代わって偽装するというのは同じですが、
スタブは単純に代わりの特定値を返すようなものを指すようです。
(例外を投げたり、違う動作をしたりはしない。)
フレームワークによって明確に作り方が違ったり、
定義にもブレがあるみたいです。
ひっくるめて偽装という事で良さそう…。
偽装クラスには、FakeXXX みたいにプレフィックスをつけるのが僕の中ではしっくり来ます。
Log String パターン
メソッドが正しい順でコールされているか確認するのに使える。
偽装オブジェクト内で、文字列変数を持ち
メソッドコールの際に文字を追記していく。
最終的に出来た文字列を評価する事で、テストが出来る。
Crush Test Dummy パターン
特定の条件で、例外が発生した場合のテストケースで使う。
偽装オブジェクトを使って、メソッドが例外を投げるような動きすれば、テストが出来る。
デザインパターン
テストコードを書くうえで、
またリファクタリングする際によく使う事になるデザインパターン
- Pluggable Object
- Pluggable Selector
- Factory Method
- Imposter
- Command
- Value Object
- Template Method
- Composite
- Collection Parameter
リファクタリング技法
リファクタリングする際に、使える技法。
インターフェイスの抽出
依存性排除のために、
実際使ってるクラスのメソッドをインターフェイス化しておく。
対象クラスは、実装に依存せず抽象化されたインターフェイスにのみ依存するようになる。
実装クラスを差し替える事ができるようになり、
テスト時には偽装オブジェクトで代替えできるようにもなる。
メソッドの抽出
一つのメソッドで多くの作業をしてはいないだろうか?
メソッドに命名した名前はその動作を端的に表す事ができる内容でなくてはならない。
命名された動作以外の事をよしなにし過ぎている場合、
それは別のメソッドに処理を抽出したほうがよい。
命名は重要。
実装コードを覗かないと何しているのかわからないものは、誤解を招き、バグの温床になりやすい。
メソッドオブジェクト
複雑化したメソッドは、一時的な変数を多く使っていたり、
処理中に様々は状態変化をもららしている事が多々あり、
単純にメソッド抽出するのが難しい場合がある。
そのような場合は、メソッド内で行っている処理自体を
メソッドクラスとして実装することができる。
一時変数や、状態を表す変数は、
メソッドクラスのメンバー変数として定義しよう。
処理のフェーズ毎にメソッド化する。
元のメソッド内では、メソッドクラスをインスタンス化して、メソッドオブジェクトの処理をコールするだけになる。
テスト駆動開発は開発スキル
テスト駆動開発は、開発スキルである。
テストという言葉がついている為、テスト技法のように捉えられるが、良い設計に導いてくれる為の開発スキルとして使うのが良い。
テストファーストだけが、テスト駆動開発ではない。
テスト駆動開発は補助輪のように作用し、実装するべきコードに導いてくれる。
進んでリファクタリングが実施できる機会を与えてくれる。
自動で品質が良くなるわけではない、
リファクタリングのよる改善を繰り返す事が大切。
テスト駆動開発を実践したとき、
これまでとは全く違う設計でプログラミングしている事に気づかされる。