先週末、TDD Boot Camp東京 for C++にTAおよび講演者として参加させて頂きました。主催の @imagire さん、登壇者として声をかけて頂いた @t_wada さん、会場提供して頂いた @mnagaku さんをはじめ、TA、参加者の方々には深くお礼申し上げます。
講演について
今回は入門者のための応用の講演ということで、TDDを実践し始めた人がぶつかるハードルへの対策を解説させて頂きました。アウトラインは以下のような感じです。
- 実践のネクストステップ
- テストを整える
- 変更に備える
- 変更に対処する
- 学習のネクストステップ
- 基礎を身につける
- より活用する
- 応用分野を学ぶ
具体的なテーマとしては、TDDで作ったテストの保守、テストの再利用、プロダクトコードの変更への対応、(時間がなく講演中に省略しましたが)テスト困難なコードの扱い方について扱わせて頂いています。また補足として、後半にてTDDの勉強の手掛かりを複数紹介させて頂きました。
講演資料:テスト駆動開発入門ネクストステップ
(番外)課題について
今回は最短経路探索アルゴリズムという複雑な処理を扱わざるを得ない課題が興味深かったです。というのも、そういった難解な処理でTDDの効率を確保しようとすると、TDDの進め方にそれなりの工夫が要求されるためです。
とりあえず補足として、今回その問題について簡単に触れようと思います。まず講演内容として想定していましたが諸々の都合で没にしたスライドを転載します。
TDDの適・不適
上図はTDDの適・不適の解説の中で、単機能テストの実装作業とプロダクトコードの実装作業の関係を示すために作ったものです。
このうち左のような構造はTDDに適している構造です。テストとプロダクトを細かいステップで交互に構築できるので、効率良くテストがプログラミングをドリブンできるようになります。
一方、最短経路探索アルゴリズムの構築もそうですが、右図のように複雑に絡み合ったプロダクトコードの塊に対しては、以下のような要因からTDDが難しくなることがあります。
- RED→GREENの粒度が大きくなり、テストの効果が断たれる期間が長くなる。
- 特定のプロダクトコードに多数のテストが過依存する構造になりがちで、テスト失敗の原因特定が困難となる。
- テストファーストやリファクタリングに必要なテストの規模が増大する。
そこでは例えテストファーストは実現できても、しばしばテストがプログラミングをうまくドリブンできません。
これと似たようなものとしては、他には組み込みの制御理論といった曖昧で複雑な計算処理や、ユーザインターフェースからユニットを検証するような上位インターフェースからの間接テスト等が挙げられます。例えば前者では、学術計算ソフト等で理想値シミュレータを構築し、それに近づくように処理を作りこんでいくアプローチでテストファーストのステップを実現できるものの、やはり前述した要因によりテストがプログラミングをドリブンする形の実現が困難です。
なお話がずれますが上記の複雑な処理をライブラリを使って実現する場合は、対応が大きく様変わりします。そこでは1つの手段として、ライブラリの仕様化テストを積み重ねることで望む機能を確保していくことになるでしょう。
絡み合ったプロダクトコードの塊への対策
こうした絡み合ったプロダクトコードの塊に対してTDDを効率よく適用するには、事前設計やプロトタイピングで、ある程度テストの見通しを広げておく必要があります。またTDDを柔軟に崩すという選択肢も十分あるでしょう。
なお仮にTDDを崩すという対処をとっても、テスト・開発の並行やこまめなテストは重要です。例えばある程度コードが確保されるたびに網羅的に潜在バグを出すようにテストを補強する等しましょう。
ちなみに今回はそうした工夫をTAながら様々な流儀で見れたのが面白くまた楽しかったです。