今回はTDD(テスト駆動開発)を行うことで得られるメリットと、TDD開発をしていく上での注意点について記事を書いていきたいと思います。

TDDで開発する3つのメリットと注意点
- 自動テストコードが資産となる
- プロダクションコードが綺麗になる
- 複雑な処理を安全に実装できる
- TDD採用時の注意点
1. 自動テストコードが資産となる
システム開発をする上で、品質はとても大事な評価軸の一つになります。
低品質のシステムを顧客に提供し不具合が発生することで、会社のブランドを気づけたり売上が減少する可能性があるからです。
しかしその一方でシステム品質を向上させるために、テストを充実させるとそれだけコストが高くなります。
そんな状況において、テストが自動化されていることは大きなメリットがあります。
しかしテスト自動化を実現するには、テストコードを作成する必要があり、初期コストはそれなりに発生します。その代わり、今後はずっと自動でテスト実行できるようになるためトータルでのコストは圧倒的に低くなります。
テスト自動化による効果は、システム開発を始めてから早くやればやるほど、より大きな効果を発揮します。
大規模で何をしているか分からないくらい巨大になったシステムでは、現行の難解でステップ数の多いコードを読み解き仕様を理解しながらテストコードを作成する必要があります。
しかし、システム開発の初期であればコード量もまだ少なく、テストコードの作成コストも低いです。
そして、TDD(テスト駆動開発)を行うメリットは、開発しながらテストコードを作る事ができるという点です。
つまり、TDDを採用することで、プロダクションコードと自動テストコードの2つの資産を手に入れる事ができるのです。
2. プロダクションコードが綺麗になる
TDD(テスト駆動開発)を行うメリットの2つ目は、プロダクションコード(以降、リリース対象のソースコードを、プロダクションコードと呼びます)が綺麗になる、です。
コードが綺麗になる理由は、テスト駆動開発の中で用いられる、TDDのサイクルで、「①テストを作成する」、「②テストを通す」、「③リファクタリング」というサイクルが何度も行われることによりプロダクションコードが綺麗になります。
例えば、最初からプロダクションコードを書いていくと、処理の一番上から順番に、何をすべきか考えて、全て処理を書き切ってしまいます。
その後、ローカルのPCでアプリを立ち上げてテストを行います。
もし単体テストや結合テストのフェーズで、不具合があった場合は、それらのケースにも対応できるように、既に出来上がったコードを改修します。
ウォーターフォール開発の場合、後半のテストフェーズに入っている場合は、プロジェクトの終盤に突入しており、不具合修正の時間で手一杯となり、バグ修正に伴うリファクタリングを行う時間はほとんど取れないでしょう。
それに対して、TDDの考え方に沿って開発をする場合、前述した①〜③のサイクルで開発を進められるためコードに無駄がなくなり、綺麗に開発されやすくなります。

①でまず、要件を満たすためのテストを作成します。
②でそのテストに合格するための最低限のコードを作ります。
③で、重複コードや可読性の悪いコードのリファクタリングを行います。
このサイクルで作っていくことで、TDDを採用しない場合と比べて、ソースコードの品質とシステムの品質どちらも圧倒的に向上します。
3. 複雑な処理を安全に実装できる
3つ目は、複雑な処理を安全に実装できる、という点です。
TDDで開発をするときに、よく一緒に用いられる考え方が、ベイビーステップという考え方です。
ベイビーステップとは、一気に処理を全部作り込むのではなく、少しずつ処理を完成させていくという考え方です。
どんなに複雑なシステムや、処理でも、一つ一つは、小さなステップを踏んでいき、処理を少しずつ足していくことで安全に開発ができるようになります。

上記の図のように、例えば自動販売機のロジックを作るときでも
最初は、150円を入れたら、お釣り30円が返却するというテストを作り、必ず30円を返却するプログラムを作り
徐々にテストパターンを増やしていく事で、どのような金額が入っても要件を満たすコードを書くことができます。
この方法では、一度に全部のロジックを作り切らずに、徐々にコードを成長させることが出来るため、複雑な処理でも少しずつ着実に実装する事ができるのです。
4. TDD採用時の注意点
TDDは、システム開発においてとても有効なプラクティスですが、必ずしも全ての開発で有効であるとは限りません。
例えば、要件がはっきりしてないプロジェクトで、プロトタイプを作成する時などは、TDDで開発をする際に注意が必要です。
その理由は、要件自体が変わってしまうと、要件を満たすためのテストも全て改修が必要になるからです。
最低限のテストコードで管理していれば良いのですがテストパターンが大量にあると要件が全部入れ替わった時にテストコードを全て修正しないといけません。
そうなると、プロダクションコードの修正 + テストコードの修正で管理コストが大きくなってしまいます。
同じ理由で、要件が毎月コロコロ変わるような画面や、ロジックもTDDでの開発には注意が必要です。そのようなビジネスを支えるシステム開発では、テストコードの管理は最低限に留めておくほうが良いでしょう。
他には、技術的な検証をする開発作業でもTDDは向いていません。
技術的にどのように作れば実現できるかは、エンジニアの試行錯誤、色々なツール導入、ライブラリ導入、など色々な技術的なアプローチをトライする必要があります。
技術的な検証で知りたいことは、技術的に実現できるか、できないか、複数の手法で実現できた場合は、どの手法が一番良いかを検証することが1番の目的となります。
それぞれの手法で、テストコードを作っていては時間が掛かり過ぎます。
そのため、技術検証を終えて、「この手法で実現する」、という方針が確定してからテストコードを含めて開発していくのが得策と言えます。

===============
この情報が皆さんの人生のお役に立てれば幸いです。
エンジニアとして日本のITリテラシーを高めていきたいと共感して頂いた人は、是非このブログの拡散とyoutubeの方も見ていただけると嬉しいです。
記事を最後まで見ていただきありがとうございました。
執筆者: hiroエンジニア