TDDとかなんかについて最近思っていたこと

つーことで kanazawa.js v1.7 が終わりまして、ようやく JS と TDD の呪縛から解放されて楽になった wtnabe です1。はてブの少なさにやや放心していたりしますが、まぁね、すでに TDD 分かってる人や興味があった人には新しい内容は何もないし、開発しない人は興味ないよねーと必死に自分を慰めています。

まぁそれはともかく、今回はリファクタリングしたかった話の続き。最近感じていることをつらつらと書いてみます。

TDDは目的ではない

これは PG_kura さんの考えや疑問

テスト駆動開発は戦略である - 偏見プログラマの語り!

を読んで、スピリチュアルなメッセージを届けようとしている自分がどうにか断言調で出した答えです。当たり前すぎてばかみたいですが、しょうがないです。そう思ったんだもん。

今回のトークでは、紹介して、さあやろうと言いながら、目的じゃないしこだわりすぎるな、無理するなできることからやれ、とやや矛盾したメッセージをそのままぶつけています。混乱されるかもしれないとは思ったのですが、今の自分の正直な気持ちです。これは以下のようなことを考えてのことです。

  • テストコードを書くことも書かないこともコストである2
  • テストコードが書けないこと、書きにくいことに対してどこまで突っ張るか決めるのは自分(たち)

これはイベントでは伝えませんでしたが、最近それなりに意識していることです。というのも、自分のテスト厨度はこれまで以下のように変化しています。

  1. リファクタリングしたいしテストを自動化して楽したい
  2. 自作ライブラリでテスト書くの楽しくなる
  3. (しばらく飛んで)TDDBC に参加してますますテストでちゃんとドライブしたいと思うようになる
  4. アプリを TDD で書く難しさを感じる
    • rspec-rails でのテストのほんとのコツは実はそんなに紹介されていない
  5. やれるところからやるに決まってんだろ(開き直り)
    • View はとりあえず従来通り目視、JavaScript も本当にややこしいと感じた部分以外はテストしない。
  6. あ、もしかしてこれでいいんじゃないか
  7. (ちょっと飛んで)そうだ、目的はリファクタリングだった
  8. てゆーかそもそもの目的は TDD でもリファクタリングでもなくね ← イマココ

つまり以前ほどにはテスト書かなきゃ、うわーっていう感情はないです。しかし今でもテストの実現方法がよく分からずに悶々として想定以上に時間が掛かってしまったりすることはありますし、当初ノーテストで進めた部分にもあとでテストを足したりはしています。

一方、TDD やテスト作成についてときどき挑発的なメッセージを発するきしださんは実は3年前に「リファクタリングできることが大事で、そのためにテストが使える」「諦めも肝心」という、この間自分の使った言葉にすでに到達され、恐ろしいまでに上手にまとめられています。

なんだよここに全部書いてあんじゃん

と思ったのですが、よくよく思い出すと関連記事を自分は当時ブックマークしています。つまり、読んでも理解できなかったんですね、たぶん。

変えればいいじゃん

今はリファクタリングや変化を包容するフレームワークのおかげで「必要になったら変えればいいじゃん」と思えるようになっています。(もちろんそれが許されるものしか作っていないわけですが。)恐らくこの状態こそが自分の望んでいた心理状態なんじゃないかなと感じています。 以前は「とりあえず」「やりやすいことだけ」やってお茶を濁していました。自信がなかったからです。

ハタから見ると YAGNI ととりあえずの違い、アジャイルとバータリーの違いは分かりにくいような気がします。でも全然違います。今はこの状態を足がかりに、これまで挑戦しにくかったことやずっとやってみたかったことにチャレンジしやすくなっている気もします。

改めてTDDをどうやって始めるか

上の自分の振り返りと TDDBC の経験を踏まえると

  • ライブラリから入るやり方はテストには慣れるけど変化には慣れないかもしれない

と思います。設計をすっきり決めやすいライブラリの場合、テストの作成に慣れ、テストを網羅するにはもってこいなのですが、テストの充実が目的化しやすいかもしれないなと感じています。

そしてここが肝心なのですが、実はこの場合はテストは開発を駆動していないかもしれないなとも思います。設計がバシッと決まりすぎてしまうものは、テストの自動化には向いていてもテストコードが開発を駆動する感じに乏しいのです。TDDBC北陸でライブラリを試しに実装していたチームの感想もそうでしたし、自分自身もライブラリからユニットテストの充実に向かいましたが、少しずつ作っているかというとそうでもないんです。テストは後付けでも全然問題ない。

だから自動テストに慣れるという意味ではライブラリから入るのはオススメですが、TDD に慣れるという意味では少し違うかもしれません。

  • テスト支援の手厚いフレームワークでアプリを作る

自分に言えるのはやっぱりこれくらいしかないです。特に Web は

  • 突き詰めると文字列のやりとり
  • 突き詰めると request と response の関数

という特徴を持っており、大変 TDD 向きです。

フレームワークから作っちゃう場合はもうどうしたらいいのか分からないです。実際には PHP でオレフレームワークを作ったことはありますが、Model 以外をテストするのはとても難しいシロモノになりました。結局自分の作ったライブラリが極めて Model 向きだったからなんですね、これ。

経験した以上のものはいきなり作れません。

「崩し」を受け止め、前へ進む

最後に TDD や OOP などに対する最近の自分の感覚を並べておしまいにしたいと思います。

  • テストしやすさのために教科書的な OO を崩すことも良し
  • 目的の達成しやすさのために教科書的な TDD を崩すことも良し
  • まったく TDD でなかった頃の自分の成果を否定しない。ログからアプリの様子が分かるのだって大事なスキル。

そのうえで、ただ消耗していく方法しか知らない状態、ただ崩すしかできない状態は否定します。それは35歳定年説に通じる道だと思うからです。自分のやろうとしていたことはがむしゃらな体力勝負じゃなかったはず。まだまだパターンなども苦手ですし、これまでチャレンジしてこなかったものも作ってみたい。体力で勝負しないんなら

智慧と勇気

でしょ。

  1. 本当はその間に Ruby技術者認定試験の Silver も Gold も受けてるので全然呪縛じゃないけど。 

  2. 書くことで一方的にコストが減るわけでも増えるわけでもない。 

More