TDDのテストと型のような話

TDD Advent Calendarの没ネタその8です。前記事のリストに入れ忘れていたので、先に取り上げておきます。
個人的にこう考えてみたというだけで、間違っているかもしれないので反論、意見等大歓迎です。あと、うまくまとまっていませんごめんなさい(なので没ネタだったのですが)。

注意事項

これは静的型付け偏重な人物が書いたものです。戯言だと思ったら戯言だと思ってスルーしてください。
また、他の静的型付け言語利用者は異なる意見かもしれないことをここに記しておきます。調査してみたいところではありますけどね。

型とテスト?

確か、TDDBC大都会の懇親会でid:t-wadaさんとの会話していた時、何かのタイミングで「動的型付けってテスト多くならないですかね」と発言してからこの話になったと記憶している。


静的型付けの場合、型チェックは基本的*1コンパイル時にコンパイラにやってもらえる。動的型付けは実行時に型の判定が行われる。期待された型と合致しない場合に暗黙的な型変換が行われるかどうかは、言語・処理系依存なのでちょっと脇においておく。
動的型付け言語の場合、型と合致するかどうかの判定や判定後の動作(分岐処理を書くか、実行時エラーなげてもらうか、etc)は開発者にお任せだろう。そして基本的に、こういった判定や型による分岐はあまり書かないのではないだろう。
TDDにせよ何にせよ、設計も考えずにいきなりコードを書き始めることはあまりないと思う。「モジュール(クラス)名はこれで関数(メソッド)名はこう、引数は…具体的なデータで考えるとhogeというデータの型はこれ、返り値は…」と、テストやコードを書くためにそれなりのことを考えるはずだ。そこには型もしくは具体値(テストデータ)も含まれる。こうして考えたことを元に開発を進める、テストを書く、設計を見直す、リファクタリングする。
ここで一つ思うこと。動的型付け言語が書ける、もしくは好き(と書くと誤解を生むかもしれないが)な人は、引数や戻り値の型を決めたときに、それ以外のデータ型をメソッドに渡さない自信があったり、仕様変更があったとしても「テストがあるから対処できる」という自信があるのではないだろうか?いや、自信はいいすぎかもしれないが。それが当たり前、という感じなのだろうか?
これならなるほど、「あなたが思っているほどの分量を、動的型付けのテストで書くわけではないよ」という言葉は納得できる。"当たり前なことに対して不安を持つか?"と問われ「不安あるよ」と答えるのは、当たり前が信頼できないか疑問を抱いているときだ。


ちなみに私は現時点では「不安かな」と答える。
静的型付けでは機械がチェックしてくれていたものを「入れないはずだからテストしなくてもいいよ」と言われて、はいそうですかと言えるほどの自信はない。あったものがなくなったのだ、不安になってしまう。そして、"不安をテストに"という信条のもと行う場合のTDDにおいて、これほどまでに書きたくなるテストはない。慣れていない、熟練度が足りないと言われてしまってはそれまでだけれども。
確かに自分だけが使う小さなコードであれば、なんとかなる。目の届く範囲だからだ。
では規模が大きくなり、複数人で開発するときはどうだろうか?"慣れ"と"動的型付け流なテスト"だけで、どこにバグが潜んでいるかを素早く発見できるだろうか?mergeした時に、型が変わっていたけどテストは全部通ってしまった、なんてことは本当に起きないものだろうか?
今の私には、判断材料がない──

まとめ

というわけで「テストたくさん書かないと…」「なんでそんなに書かないといけないと考えたの?」という話を思い出しながら書いたよ、というなげっぱなしな記事でした。

*1:リフレクションやvoid*はあえてスルーしておく