このエントリは Advent Calendar 2013 4日目の記事です.
前日のエントリーは,comuttさんのvim + py.test で TDDでした.
アサートファースト
このエントリでは「テストコードの書き方」,特に,
- テストコードの中身をどの順番で書き進めるか
についてまとめます.
TDDと言えば「テスト・ファースト」ですが,Kent Beck は,さらに「アサート・ファースト」によるコーディングを提案しています.
アサートをいつ作成するべきなのか. → 最初に作成するべきである.
では,次のテストメソッドを書くとき,どのような順番でコーディングするのがいいでしょうか?
public void add_return105() { Money sut = new Money(100); Money other = new Money(5); assertThat(sut.add(other), is(100 + 5)); }
アサートファーストを採用すると,次のような順番で書きます.
// 3: テスト名を付ける public void add_return1() { // 2: assert文に必要なオブジェクト(sut/other)を作成 Money sut = new Money(100); Money other = new Money(5); // 1: 実現したい機能をassertで表現 assertThat(sut.add(other), is(100 + 5)); }
実際にコーディングするときは,次のようなイメージで実装します.
- まずはテストしたい仕様をassert文で書きます
- つぎにassert文に必要なオブジェクトを作ります
- 最後にテスト全体の内容を確認しながらメソッド名を決めます
IDEの助けを借りる
先の順番にコーディングすると,assert文を書く時点でsutが宣言されていないため,IDEがメソッド名を補完してくれません.
そこで,現代っ子は先にsutを宣言するのがベストかと思います.
// 4: テスト名 public void add_return1() { // 1: テスト対象のオブジェクトを作成 Money sut = new Money(100); // 3: assert文に必要なオブジェクトを作成 Money other = new Money(100); // 2: sut がみたす仕様をassertで表現 assertThat(sut.add(5), is(100 + 5)); }
プログラマの負担を軽くすることがすべて
テスト駆動開発のメリットは,プログラマの負担を軽減できることです.
一度に複数のことを考えるのは,(できたとしても)楽ではありません.
テスト内容をぼんやりとイメージしながらコーディングするのではなく,assert文という明確な目的を何よりも先に設定することで,頭の中をクリアに保てます.
テストに導かれてプロダクションコードが生まれるように,テストコードはassert文に導かれるべきです.
アサートファーストで気楽にプログラミングをしましょう!
Advent Calendar はまだまだ続きます
明日,12月5日の担当は2回目の登場 setoazusa さんです.
よろしくお願いします.