初めてのテスト駆動開発(TDD)と感想


TDDに出会うまで

Unixにまつわる本やUnix系の技術書は読んできたのですが、開発手法についてはまったく手を出していませんでした。会社員になり学生時代と比べて時間の余裕がなくなると読書は通勤電車で済ませるようになり、手を動かせる時間はなるべくFLOSSを調べたり書いたりするようにしていました。

手を動かす必要がある技術書は電車で読むには不適格すぎるので、読んだだけでとりあえず知識として頭の片隅に入れておけるような、開発手法やマネジメントの本にも手を出し始めたのが2018年からでした。本を買っては積み上げ読んでいく生活をして、ついにKent Beckの『テスト駆動開発』とKent Beck・Cynthia Andresの『エクストリーム・プログラミング』に出会いました。

読んだのは後者が先でした。「XPでは、できるだけ実装前にテストを書く」(『エクストリーム・プログラミング』, p.97)とのことでした。頻繁なテストが欠陥数を下げるという主張には同意できましたが、テスト職場でも趣味のコード書きでも、ソフトウェアの「動作確認」こそすれども「ユニットテスト」は経験がありませんでした。コードへのテストに対しても、「自分で書いたコードをテストするなんて、絶対テストが通るようにテストを書くに違いないだろう」という偏見がありました。要するにTDDが何なのかまったく理解していなかったのです。

『テスト駆動開発』を読んでからは、とりあえずこの不理解は解消されました。テストは必ずしも動作確認のためだけではなく、コーディングや設計の指針も示してくれるらしいのです。PythonによるxUnitの実装の演習はこなしましたが、写経するだけならなんでも順調に進んでしまいます。テストを先に書く利点をあまり実感できませんでした。

実践

もしなにかしらのコマンドラインツールを作るのであれば、そのときはTDDでやってみようと考えました。ちょうどConoHa VPSでマシンを契約していて、コマンドラインから仮想マシンを操作できればなと思っていたところでした。APIは提供されていたので、PythonでAPIのWrapperライブラリを書いてコマンドラインツールを作ろうと思い立ちました。

成果物はhttps://github.com/user340/conohactlです。最初のcommitから数えると11日ほどかかりました。Pythonのドキュメントを調べたりあまり手が動かなかったりとペースは遅かったのですが、最低限自分がやりたいことは実現できました。

TDDを実践してみて「これが良いな」と思ったことがいくつかあります。

インタフェースを明確にできる

テストを先に書くことで、これから実装しようとしているメソッドがどのようなインタフェースを持つのかを明確にできました。たとえばテストの中でこれから書くべきメソッドを呼ぶだけで、どのクラスにどのような名前のメソッドを書くのか・引数/戻り値はなにかが決定します。なにが渡されてなにを返すのかをあらかじめ決めたわけですから、迷わずコーディングができました。

テスト側で一度メソッドをどう呼び出して戻り値をどう処理するかを書くことになります。したがって、テスト駆動で書いたライブラリを呼び出すユーザプログラムを書くときは、テストと同じようにメソッドを呼び出して戻り値を処理すればいいのです。テストコードがすなわちリファレンスになるということです。これは本当にありがたいことでした。

例外処理が書きやすくなる

テスト対象のメソッド内で、不正な引数が渡されたときや意図しない値が返ってきたときの挙動を決めておかないと異常系のテストができません。起きてほしい例外をテスト側で待ち受けることが、本体の例外処理はどう書けばいいのかという指針になります。

自信がつく

テスト第一で開発すると「このメソッドは(自力で考えられる範囲で)十分にテストしてうまく動作するはずだからcommitしていい」と思えるようになります。テストが通っているコードは自信を持って扱えられます。

振り返り

最初はテストとはなんぞやという認識から始まりましたが、一旦やってみればテストの利点もTDDの利点も両方把握できたように感じます。TDDを実践して「どうテストするか?」を考えながらコードを書くと「クラスの設計をどうするか?」という問題も意識することになります。TDDはコーディングの指針が立てやすくなる開発手法だとわかりました。

ただ、Beckがやったような一歩ずつテストを実行して失敗を確認してからコードを書くようなやり方はあまり馴染みませんでした。テストはテストで一通り書いてから本体を書いてテストを実行するほうが性に合いましたし、手順が細かすぎずコーディングが中断される回数が抑えられました。おそらく趣味や慣れの問題だと思われます。

振り返れば、新しい開発手法を試せて良い経験になりました。これをできれば職場でもやりたいですし、職場でしかできなさそうなペアプログラミングやモブプログラミングなどの手法も試していきたいです。