TDD (テスト駆動開発)まとめメモ

本投稿はテスト駆動開発の第3章(まとめの部分)を読み,UdemyのTDD講座受講したことから得た知見をまとめる目的で執筆します. 内容的にはTDDで開発する理由やメリット,注意点についてまとめようと思います.

TDDとは?

実際のコードよりも先に失敗するテストコードを書き,そのテストが通るように実装していく開発手法です.

なぜTDD?

なぜTDDで開発を行うと良いのかは主に2つ目的があります.

エラーの発生を少なすることができる

以下の図を見て下さい.左側がTDDではない場合のストレスとエラーの因果ループ図であり,右側がTDDで開発を行った場合のストレスとテストの因果ループ図です.左側はストレスが増加するとエラーが増加してしまう正の接続を表し,右側はストレスを感じた際にテストを実行することでストレスを下げるという負の接続を表します.

f:id:harada-777:20200602211658p:plain

TDDで開発行わない場合例えば,何かを変更したときや実装したときにそれは正しいのか?という疑問を抱ながらコードを書き続けなければなりません.これはストレスを感じたままコードを書き続けることとなり,するとエラーの発生が増加してしまいます.しかしTDDで開発をする場合は,ストレスを感じたらすぐにテストを実行でき何も壊していないことや意図通りの動作をしていることが確認できるので,ストレスを下げることができます.そうすることでエラーの発生を防ぐことができる.

設計を強制することができる

テスト駆動で開発をすると必ずテストを書くことになります.するとあるときテストを書こうとすると以下のような違和感を感じることがあります. + テストをする前の準備が長い + テストの実行時間が長い

こういう違和感は設計を見直すサインとなります.テストをする前の準備が長いのはテストに必要なオブジェクトの生成が大変なのが原因だったりします.これはオブジェクトを分解する時が来た時を教えてくれます.テストの実行時間が長いのはテスト対象の関数がやっていることが多すぎることを示唆してくれています.関数の責務を見直し分割することを検討してみましょう.

どうやってTDDを行う?

TDDは必ず以下の手順に従います. 1. レッド + まずは失敗するテストを先に書く 2. グリーン + テストを通す最小の実装を書く 3. リファクタリング + テストが通り続ける状態でコードの重複などの変更を行う

レッド

TDDではまずテストから書き始めます.このときのポイントとして必ず失敗することを確認します.そもそも実装がないので失敗するのは当たり前なのですが,アノテーションのつけ忘れ等でそもそもこのテストが呼ばれないことを防ぐ為に必ずこのことを確認します.

グリーン

テストが落ちることを確認した後にはテストを通す最小のコードを記述します.テストを通す最小のコードって何?って思われるかもしれませんがこれは値をベタ書きするということです. 例えば以下のように昨日を求める関数を実装したい場合はまず以下のようなテストに対して

assertEquals("2020-01-01", calculator.yesterday("2020-01-02"));

以下のように直接値を返す関数を実装するということです.

public String yesterday(String: date) {
    retrun "2020-01-01"
}

なぜこのようなことを行うかの理由は主に3つあります + テストのミスに気付ける + 具体例から徐々に一般化する方が考えやすい + グリーンとレッドでは精神状態が違う

特に2つ目のいきなり難しく一般化しようとせず徐々に一般化した方が,結果的に早く一般化されたコードに辿りつけるというのは開発あるあるだと思っています笑

テストを書くときの注意点

常にレッドバーから始める

前述した通りこれは呼び忘れ等を防ぐ為に重要なことです.

ロジックに対してテストを書く

テストとメソッドは常に一対一という訳ではありません.ロジックに対してテストがあるべきです.プライベートメソッドにテストを書きたくなる時は,設計を見直すタイミングです.これは何かをパブリックメソッドでは?と考える機会を奪ってしまいます.

いつでも動くテストを書く

ある特定な時間にしか動かないテストを書いてはいけません.思わぬ時に失敗するテストは思いもよらないところが影響を与えている可能性があるので設計やコードを見直しましょう.

十分な量のテストを書く

テストはどれぐらい書くべきか?という答えにテスト駆動開発は「不安が退屈になるまで」と答えています.つまり安心できるまでということです.もう少し具体的なこととしてUdemyの講座に出てきたテストを書くときのポイントを載せさせて頂きます. + ロジックはどうあるべきか + ロジックの反対のことはわかるか + エッジケースは確かめられているか + エラー条件を確かめられているか

感想

テスト駆動開発はxUnit部分などライブラリに関する部分やIDEのリファクタに関する部分など古い部分はあるものなぜそうするか?という部分が割と書かれている点でいい本だと感じました.一方で具体的な手法は新しい媒体で身に付ける方がいいと感じました.