
はじめに
近年、AgileやScrumの普及に伴って、振る舞い駆動開発(Behavior Driven Development、以下BDD)や受け入れテスト駆動開発(Acceptance test–driven development、以下ATDD)にも注目が集まってきました。
そこで本連載では、BDDやATDDとは何か、どのように活用すれば良いのか考えていきたいと思います。
本連載の構成は以下の通りです。

本連載のメインであるBDDやATDDは、テスト駆動開発(Test-driven development、以下TDD)から派生した考えです。つまり「TDDとは何か」という理解がないとBDDやATDDを理解することが難しくなります。そこで今回は、TDDとは何か、TDDの目的は何かについて改めて考えてみましょう。
本連載を読み始める前に確認してほしいこと
対象読者について
本連載では、以下のような読者を対象として考えています。
・TDDのやり方を知っている、もしくはTDDを実践している
・BDDという単語は聞いたことある
・BDDのやり方は知らない
本記事でTDDのやり方については語りません
本記事では、具体的なTDDのやり方については割愛します。
理由としては、既に素晴らしい教材がネット上にあるからです。特に、TDD Bootcamp 2020 Onlineの和田卓人さんによる基調講演(動画)は是非ご覧ください。文字上でTDDを語るよりも多くの有益な考え方が示されています。
本記事では、TDDのやり方を知っている前提で、なぜTDDを行なうべきか、何を目的としているのかについて話します。
TDDはテスト手法ではなく開発手法である
「TDDとは開発手法もしくは設計手法の1つである」という理解が必要です。特に、TDDという名前から「テスト手法の1つである」という勘違いが非常に多いです。
TDDとは、「テストの方法」ではなく、あくまでも「手段としてテスト(テストコード)を用いた開発方法」です。
TDDは以下の3つを満たしながら作成していきます。
・Red…設計の指針や直近のゴールを明確にする(そのためにテストコードを記述する)
・Green…ゴールを達成する(つまりテストコードがPassする)コードを愚直に実装する
・Refactor…ゴールを達成させたまま(つまりテストコードがPassしたまま)、実装したコードを改善していく
ゴールを示す具体的な手段としてテストコードを用います。
BDDを考案したDan Northも自身の記事「We need to talk about testing(邦訳:テストについて話し合わなくてはならない)」の中で、以下のように述べています。
TDD、BDD、ATDD、および関連するメソッドは、その名前が示すように、テストに取って代わるものではありません。これらは主に設計および開発手法です。
(中略)
プログラマーは自分が単体テストを書いていると思っています。そうではありません。彼らは、設計の指針となる簡単な具体例をテストコード形式で書いているに過ぎません。
TDDを行う主目的は素早くフィードバックを得るためである。
TDDとは、「手段としてテストを用いる開発手法」という説明をしました。
それでは、なぜTDDを行うのでしょうか?
TDDを行う主目的は、「素早くフィードバックを得ること」です。
開発をして、顧客からフィードバックをもらうには、通常1週間以上、長いと半年以上かかります。これは、リリースサイクルや顧客との関係性によって期間が変わります。この状態だと、フィードバックを貰った時に、開発が終わってからかなりの時間が経っているため、そもそもどのように開発したのか思い出したりするところから始めることになります。(以降の画像および説明は「私が経験したソフトウェアテストの変遷(JaSST’18 Tokyo招待講演)」を参考に作成)

それでは、顧客からのフィードバックが来るまで待ち続ける必要があるのでしょうか?そうではなく、もっとフィードバックを短くする方法があります。
例えば、「受け入れテスト」などと名付けて、リリース前の評価環境で実際にテストしてフィードバックをするかもしれません。

これならば、顧客に提供するよりは短い期間でフィードバックを行うことができます。しかし、まだまだフィードバックまでの期間が長くなります。
そこで、システムテスト、統合テスト、単体テストなど様々な手段によって、もっと短いフィードバックを検討することができます。

ここまで書いた「単体テスト」「統合テスト」「システムテスト」「受け入れテスト」は、品質保証手段として行われるテストです。([注釈]JSTQBシラバスのテストレベルの記載を参考に単語を選定しました。実際の現場では、「APIテスト」「UIテスト」など、違う単語を用いているかもしれません)
一方、品質保証を目的としないで作成するテストとして、開発者自身が作成するxUnitテストがあります。
テストを作る目的は違いますが、フィードバックまでの長さという軸で見ると、xUnitテストは他のテストよりも短いことが分かります。

それでは、xUnitテストの実施が一番短いフィードバックなのでしょうか?いえ、さらにフィードバックを短くすることができます。
実装とUnitテストの作成の順番を逆にすれば良いのです。
これがテストファーストな開発です。この考え方を用いているのがTDDです。

TDDは、上に書いたテストファーストな開発の考え方に加えて、「失敗するUnitテストを1つ作成したら、そのテストがPassするように実装を行う」「テスト実行を終えたら、次のUnitテストの作成を行う前に、リファクタリングによるコードおよび設計の改善を行う」という考え方も必要となります。
TDDもテストファースト開発の1つとして考えると、TDDを行う主目的は「素早くフィードバックを得ること」と考えて良いでしょう。
つまり、如何に素早いフィードバックを得て開発に活かすのかという、開発手法および設計手法としてTDDがあると考えることができます。
TDDによってどの程度素早くフィードバックを得ているのかについては、TDD Bootcamp 2020 Onlineの和田卓人さんによる基調講演(動画)をご覧ください。
また同様の主張については、やっとむ/安井 力(やすい つとむ)さん作の記事「テスト駆動開発(TDD)への招待」もご覧ください。
回帰テストへの流用という副次的な効果
TDDを行う主目的は「素早くフィードバックを得ること」ですが、実際にTDDを行なって得られる副次的な効果として、回帰テストへの流用があります。
TDDで作成したテストは自動化されているため、そのまま回帰テストの材料として利用することができます。
つまり、別機能を開発する際のデグレードの防止に役立つのです。しかし、これはあくまでも副次的な効果です。TDDの主目的ではありません。
品質保証の考え方を注入する
ここまでで、TDDを行う主目的は「素早くフィードバックを得ることである」という説明をしました。それに加えて、品質保証を入れることも目的の1つとして、TDDに取り組むことはできないのでしょうか?私は可能だと思っています。
その具体的なやり方については、秋山 浩一さん作の記事「Fizz Buzz問題とTDDとテストと」をご覧ください。
次回予告
今回はTDDとは何か、TDDの目的とは何かについて話しました。
次回は、BDDがどのような考えで誕生したかについて話します。
連載一覧
TDDとBDD/ATDD(1) TDDはテスト手法ではない
TDDとBDD/ATDD(2) 2種類のBDD
TDDとBDD/ATDD(3) BDDとATDDとSbE
TDDとBDD/ATDD(4) ツールとしてのBDDとプロセスに組み込まれたBDD
TDDとBDD/ATDD(5) BDDのプロセスその1「発見(Discovery)」と実例マッピング
TDDとBDD/ATDD(6) BDDのプロセスその2「定式化(Formulation)」とBRIEFの原則
TDDとBDD/ATDD(7) BDDのプロセスその3「自動化(Automation)」