TDD の基礎体力と、TDD に対する想い

TDD Advent Calendar 2011 の 4 日目の参加エントリです。
前半では、TDD を学ぶ前に身に付けておくといいと思う基礎体力について書きました。
後半は、まぁ、その。後悔はしていません。反論ウェルカム、議論しようぜ。

不安をテストに

「レッド - グリーン - リファクタリング」は、TDD の根っこの部分であり、これ自体が「どう TDD をやればいいか」を教えてくれるものではありません。
それに対して、「不安をテストに」というのは、「どう TDD をやればいいか」という指針を与えてくれる言葉です。


この言葉自体は、TDD Boot Camp で自分のものにできました。
不安については、テスト駆動開発入門では (言及されているものの) 自然に組み込まれていて、最初に読んだときには全然気づきませんでした。
しかし、TDDBC で id:t-wada (和田さん) に短くてわかりやすい言葉にしてもらえたことによって、「不安」について意識してテスト駆動開発入門を読めるようになりました。

TDD の基礎体力

で、指針として「不安」というものを使うということは分かりました。
問題になるのは、開発者によって「不安」に思う場所というのが全然違う、という点です。
今まで自動テストを書いたことが無い場合、「何が不安なのかすら分からない」となる人もいるでしょう。


思うに、TDD をうまくやるための、基礎体力とでも言うべき事柄があるのです。
これさえ押さえておけば TDD できる、というものでもないですし、これを知らなければ TDD できない、というものでもないですが、知っていたほうがすんなり TDD を受け入れることができるでしょう。
それは、

です*1

テストに関する知識

TDD のテストは、Developer Testing と呼ばれ、品質保証を目的としたテストではありません。
しかし、どういうテストを書けばいいのかに対する指針には、そういうことを目的としたテストの考え方が使えます。
品質保証を目的としたテストの考え方を知っていれば、どういう部分が不安になるのか、というのも考えやすいでしょう。


ただし、深入りしすぎると危険だとも思っています。
もう一度言いますが、TDD のテストは Developer Testing であって、品質保証を目的としたテストではありません。
なので、例えばカバレッジだとかを TDD のテストに対して求めるのは多分違っている。
あくまで、「不安を感じることができるようになるために」品質保証を目的としたテストを学ぶのがいいでしょう。


もちろん、「TDD でカバレッジなんて取るな!」と言っているわけではありません。
カバレッジを指針として使うのはアリでしょう*2
しかし、カバレッジ○○% を目指してテストを書くだとか、TDD やっていればカバレッジは 100% になるはずだからそうなっていないのは TDD ではない、というのは違うんじゃないかな、という話です。

設計に関する知識

プログラミングに対して、具体的な不安を感じることができるようになりました。
しかし、それでもまだ TDD をうまく回せないかもしれません。


作りたいものはある。
そしてコードを書こうと思った時に不安を感じることもできるようになった。
でも、「最初の一歩」をどう踏み出せばいいか分からない。
そういう状況です。


なぜ最初の一歩が分からないかというと、到達可能な具体的なゴールを定めることができないからです。
で、到達可能な具体的なゴールを定めるのに必要なものは何かと考えると、大きい問題を小さい問題の集まりに分割する力です。
大きい問題を小さい問題の集まりに分割するというのは、つまりは設計を考える、ということです。
ここで有用なのが、デザインパターンをはじめとするパターンです。
「このパターンはこういう状況で適用できる」という感覚をたくさん自分の引き出しの中に持っておけば、大きい問題でもまだどうにかできそうな粒度まで落とし込めるようになるでしょう。


ただし、ここでも注意が必要です。
パターンはあくまで「最初の一歩を踏み出すため、問題を小さくする」ことを目的としています。
なので、最初に (おぼろげに) 考えたパターンに固執することの無いようにする必要があります。
最初の一歩を踏み出し、テストによって開発及び設計を駆動していたら、当初思っていた設計とは全然違うものになった、ということもあり得ます。
もちろん、最初に考えた設計に行きつくこともあり得ます。

リファクタリングに関する知識

不安に感じる力も得た。
最初の一歩も踏み出せるようになった。
ある程度、TDD のようなものができるようになったような気がする。


でも、ちょっと待ってください。
そのコード、リファクタリングしてますか?
ここで id:t-wada の講演を引用します(スライドは福岡の時のものです)。27分あたりです。


これ(リファクタリング)だけが汚いときれいの間を突破できる力になるわけです。
テスト駆動開発とかテストの自動化の話をしているとみんなテストに注目しちゃうんですね。
〜略〜
忘れてはいけない一番大事なもの。要するに、きれいな方向にシステムを持っていけるのは、リファクタリングなので、リファクタリングのことは忘れてはいけません、というのを僕はいくら強調してもしたりないことです。

TDDBC Tokyo 1.5 基調講演

講演の動画自体、是非全部見てほしい内容なんですが、1 時間 10 分あるので時間のある時にじっくり見ることをお勧めします。


で、話を戻してリファクタリングについて。
リファクタリングをうまくやるためには、「きれいなコード」というのを知っていなきゃいけないんですよね*3
きれいなコードは、良書と呼ばれる本を読んだり、実際にきれいなコードを読み書きすることで分かってくるものです。
そのためには、やはりファウラーのリファクタリング本はせめて一度は目を通しておくべきです。
ファウラーのリファクタリング本以外だと、パターン指向リファクタリング入門という本もお勧めです。

TDD の基礎体力を身に付けた後

実践あるのみです。
id:t-wada の言葉を借りると、「量は質に転化する」です。
俺は「実践の数をこなすことのみが TDD 習得の唯一の道」くらいに考えています。
後は、TDD のリズムを身に付けるために、TDD Boot Camp には是非一度参加してもらいたいです。

ちょっと一休みして TDD の適用可能性について

話は変わりますが、「TDD によるプログラミング入門」的なものって、難しいと思うんですよね。
何が言いたいかと言うと、全くのプログラミング初心者が TDD を学びながらプログラミングを学んでいく、というのは無理がある、ということです。
で、この話の延長線上に、上で述べた「TDD の基礎体力」がある。
つまり、TDD「だけ」にフォーカスを当てて習得しようとしても、なかなか難しいのではないでしょうか。
TDD には*4、その基礎となる技術が存在して、それらもある程度やったほうが、より効率よく TDD を習得できるのです。


また話は変わりますが、TDD の向かない分野についての話題です。
TDD はもちろん銀の弾丸なんかではなくて、現状 TDD では立ち向かうことのできない場合も確かに存在します。
テスト駆動開発入門でも、

(少なくともまだ) テストだけでは駆動できないプログラミングタスクが存在する。
たとえば、セキュリティソフトウェアと並列性に対しては、ソフトウェアの目標達成を機械的に証明するのに TDD だけで十分とは言えない。

とあります。
しかし、だからと言って「自分の関わっている分野では TDD は無理だ」と最初からあきらめてしまうのは悲しいことです。
TDD が全くこれっぽっちも入り込む余地のない分野なんて、そうそうないと思うのです。
上で引用した文ですが、「テストだけでは駆動できないプログラミングタスクが存在する」と、あくまでタスクレベルの話をしているんですよね。
これまたテスト駆動開発入門の引用ですが、

このようなごく小さな手順をここでも踏むことについて弁解しよう。
読者が実際にこの方法で作業するように勧めているわけではない。
この方法で作業できるようになることを勧めているのだ。

とあるように、TDD を自分の引き出しに入れておくということは、「小さいステップを積み重ねて問題を解決する手段」を用意しておくということでもあるのです。

TDD 三原則について

と、ここまでは割とおとなしめモードだったわけですが、ここからはちょっと攻撃的に行こうかと思います。
TDD 三原則について、Dis ります。モヒモヒ。

TDD 三原則とは

Bob おじさん提唱の TDD に関する 3 つのルールで、

  1. 失敗するテストを成功させるためにしか、プロダクトコードを書いてはならない
  2. 失敗させるためにしか、テストを書いてはならない
  3. テストを 1 つだけ成功させる以上に、プロダクトコードを書いてはならない

です。

TDD 三原則という訳について

これ駄目でしょう。
原文では「The Three Rules Of Tdd」、もしくは、「The Three Laws of TDD」です。
原則って言うと principle が真っ先に思い浮かぶんですが、原文では principle じゃないんですよ。


「TDD 三原則」って言葉は確かにインパクトありますよね。
三原則と聞くと、日本人の多くは「非核三原則」が頭によぎると思うんですが、こちらは principle です。
で、「非核三原則」は日本人にとって、非常に重い意味を持っている。
なので、語感として「TDD 三原則」というのは、その言葉の元々の意味以上の意味を持ちかねないんです。
「TDD の 3 つのルール」くらいに留めておいてほしかった。

コードの追加しか見ていない

リファクタリングについて、何も述べてないんですよね。
テスト駆動開発入門の vi ページから引用すると、

レッド - グリーン - リファクタリング ― これが TDD の信条である。

と、リファクタリングは重要です。このエントリの前半でも言及しました。
でも TDD 三原則にはリファクタリングについてのルールがないので、元からして「足りてない」感が否めないのです。

手順しか見ていない

「どういう手順でやるか」しか見てないのも残念です。
これは語感の話ともかぶるんですが、「TDD 三原則」と言われちゃうと、

  • それを守らなければ TDD ではない
  • それを守るだけで TDD になる

の、少なくともどちらかのことは言っているような気がするんです俺は。
でも、この 3 つのルールだけではテストによって開発や設計を駆動させることはできません *5
だって手順についてしか言及してないんだもん。

つまり何が言いたいか

まぁそんな理由によって、俺は「TDD 三原則」があまり好きではない。
確かに、あれを守るのは TDD 習得の近道にもなるでしょう。
でも、それはあくまでOOコード養成ギブスの TDD 版のようなものなんです。
それだけを見て TDD をやろうとしても、挫折する人が増えるだけなんじゃないか、という危惧があります。
せめてもう少し、TDD を学ぶ上での指針を提供してあげたい、そういう意味も込めて前半部分を書きました。


とまぁそんな感じです。
明日は TDDBC 札幌の @shuji_w6e さんです。
TDDを学ぶべき10の理由 #TddAdventJp - やさしいデスマーチ

*1:もっと掘り下げていくこともできますが、直接関係するのはこの 3 つが大きいかな、ということで今回はこの 3 つの話

*2:このパス通ってないけど大丈夫なんだっけ?と考えるための指針とか

*3:きれいなコードを知る、というのは、まずいコードを知る、と言うことでもあります。「コードの臭い」というのもそれですね。

*4:これは TDD に限った話ではありません

*5:なので、少なくともそれを守るだけで TDD になるわけではない