- クロコさんからの質問
前回お話しされた,レッド,グリーンのサイクルの最小単位は,どうやったら体でつかめますか?
なるほど。連載第5回でも,「写経をやってみた,リズムもわかってきた。でもいざ自分でやろうとすると,最初はどういうテスト書こうかとか,どういう単位でテストを書けばいいのかとかで詰まってしまう」という質問をいただきましたね。
私は実は,明確にこういう単位でテストを書くべしという決まりはないと思っています。
不安をテストで表現する
では,私がどういうときに小さいテストを書いているかというと,私は「不安」を最小単位の基準としています。不安を手がかりにしてテストを書きます。
私たちプログラマの手を止めるものは何でしょうか。私は「不安」だと思っています。「もしかしたら」という感情ですね。「もしかしたら,自分の書いているコードは間違っているかもしれない」「もしかしたら,ライブラリの使い方が正しくないかもしれない…」。
私は不安に対してテストを書いていますから,自分がこれから書くコードに対して自信を持っている,たとえばこれまで書いたことのあるコードによく似ているコードなのであれば,小さい単位のコードは書きません。
対照的に,これから書くコードに自分自身が不安を感じているようであれば,小さい単位のテストを書いてみます。小さい単位というのは,1メソッドに対するテストや,メソッドの中の一部分に対するテストです。
プログラマとしての私は,if文の条件部分のミスや,配列をループしたりするときにカウンタ値を1個間違えてしまう(フェンスポストエラー)といった,すごい単純ミスが多いんですね。
『WEB+DB PRESS Vol.35』のサンプルの例でいえば,URLをスラッシュでちょんぎって配列にするとか,正規表現を使って文字列を抽出するというときに,私自身は一発で書く自信がありません。
だから,これから書くコードに対して,if文があるだろうなとか,ループがあるとか,正規表現使わなきゃいけないなとか,そういった自分自身に対する不安,これから書くことに対する不安に対して,テストを書いていきます。
学習テスト
「学習テスト(Learning Test)」という言葉があります。
これからコードを書く際に,自分が使おうと思っている技術,たとえば未経験のライブラリの使い方に対して不安がある場合に,それをテストの形で書いて技術検証することを「学習テスト」と呼びます。
たとえば,正規表現を使って,何らかのパターンマッチング,ある文字列の中のあるパターンの部分と,もう一つのパターン部分を抽出するようなコードを書かなければならなくなったとします。
そのようなときにまず最初に私がやることは,いきなりそのメソッドのその機能そのクラスのテストを書き始めるのではなくて,テストケースの中で,たとえば正規表現のクラスライブラリに対してこういう入力をしたらこういう出力が返ってきたという,ライブラリの使い方を調べる単純なテストを書いていくことが多いんです。
私は何回やっても忘れてしまうことが多いため,暗記できないものに関しては,自分でその場でライブラリの使い方などに対するテストを都度書いていって,その使い方が機能する(テストがグリーンである)ことを自信の根拠にします。
学習テストの成果は開発に還元する
そして,学習テストの成果は開発に還元します。
たとえばそのテストコードの中で勉強したことを,実コードに写してみるという形で,テストコードの中からそのテストコードの中のメソッドを取り出して,そのメソッドを実クラスにリファクタリングで移動したりします。
また,テストコードの中で試しに書いたコードを,テストクラスの中で内部クラスとして抽出し,その内部クラスをトップレベルクラスの形にリファクタリングしていって,そのクラスをテスト対象の実コードとしてさらに育てていく(Incubatorパターン)という使い方もあります。
今回説明したような,一番最初はテストコードの中で,これから書くコードの中で自分の不安な部分を試しにテストとして書いてみる,そして小さいステップを踏んで,一歩一歩,最初は自分がよくわからないところを中心にして,段々に歩みを進めていくというようなやり方をよく行います。