JUnitが当たり前になり、TDDが普及し始めた今だからこそ改めて問う

皆さん、JUnit作ってますか?TDDしてますか?

ぼくも作ってますよー!JUnit!わっしょい!TDD!わっしょい!

はい。

で今日、言いたいこととしては、JUnitをみんな当たり前に作っているけど、どうなのそれ?っということです。

先日、オブラブの夏イベントに参加して来たんだけど、そのときのid:t-wadaのセッションで「テスト工藤開発者は三週目で死ぬのか」を聞いていて色々感じることがあったのとこれまでJUnitに対して思いがあるので吐き出してみる。

JUnitについて批判的な内容を書くけど、本当はJUnit大好きだからね。TDDも大好きだよ!

発端

セッションで、TDDの経験者の人という質問にかなりの人が手を挙げていた。オブラブ補正が掛かっているとは思うけど、ここまで流行っているのかと正直驚いた。おい、みんなどうした目をさませ!

ぼくはJUnitのメリットは十分理解しているけど、駄目なところも嫌と言うほど身にしみている。最近は、TDD最高!JUnitガンガン作ろうぜ!みないなノリが体勢を占めていて、JUnitの問題点が語られることは少ない。みんなは苦労してないの?

JUnit工数が掛かる

これについては、見積もりの段階からJUnitの分を積んどけばいいのかも知れないけど、正直、JUnitを作るのは時間が掛かる。ぼくの経験上、実装と同程度の時間が掛かる。DBのデータをExcelで作ったり何かしらの共通機能を作成するとさらに別途時間が掛かるし、ある程度のルールを作る必要があるのでその分がさらに追加になる。

GUI系(Webとかデスクトップアプリとか)だと、これまで画面カチカチの試験だけでやっていた人にとっては、どんだけ工数かかんだよ!って感じだよね。

ま、これはみんな意識しているところかも。

仕様変更や機能追加でテストケースが軒並みレッドになる

テストケースを作っている理由の1つに仕様変更や機能追加に迅速に対応することってことがあると思うんだけど、これはOK?

でも仕様変更や機能追加してJUnitを動かしたら全然動かなくなったっていう経験ない?ぼくはある。まぁ、仕様が変わったりしたら当然だよね。だって、画面に表示する内容が変わったりしたら正解が変わるんだから当たり前だよね。でグリーンにするために同じような面白くない修正をたくさんしなくちゃいけなかったりする。

あれ?テストケースを作るメリットって迅速に仕様変更や機能追加するはずじゃなかったの?明らかにやること増えている。テストケースがあるがために作業が増えてしまっている。

これについては、id:t-wadaも言っていた。

カバレッジを通すのが目的になる

これはよくある話。普通は、テストケースを作るからにはC1カバレッジ100%とかなんとか値を設定するんだけど、もうテストなんてどうでも良くなっちゃってとりあえずカバレッジ通るように意味のないテスト書いちゃったりする。あれ、このテストケース、assert少なくない?とかね。

コードを書くのが億劫になる

コードとテストケースは普通セットで作るよね。コードだけ作って、テストケースを作らないなんてありえない。
そうなってくると、上でも言ったけど、コード書くのとテストケース書くのは同じくらい時間が掛かる。
コードだけなら片手間にサクって作れるような機能でもテストケースがセットとなると気が重くなる。まぁ、これは主観的な部分が多いのかも。

JUnit作るのつまんなくね

個人的にはこれが大きい。JUnit作るのは、正直つまらない。何であんなにつまらないのだろう。作っていて精神修行かと思うもん。
MapやBeanの比較とかだと何回assert書かせりゃ気が済むんだよって感じがする。そもそも時間が経ってくると普通のソースよりテストケースの方が読みにくくなってきたりするもん。JUnitリファクタリングとか、お客さんに説明しにくいから、機能追加とか何かのついでにやらなきゃいけないし。

無駄にnullの試験とかやっちゃうよね

最近はフレームワーク全盛の時代だから、自分以外の書いた機能を使うことも少なくないんだけど、そいつの戻り値がStringだったとして、値にnullが渡ってくるのか""が渡ってくるのかって正直すぐにわからないよね。例えば、request.getAttribute("hoge")で対象の値がないとどっちが返ってくるかなんてやってみないとわからない。だから、nullが渡ってくる場合の試験と""の試験をやったりする。実際に画面とかと連携して動かしたら絶対に起こらないのに。

結局画面カチカチはしなくちゃいけない

GUI系のプログラムありきで話しているけど、テストケースが全部グリーンです。じゃ、リリースしよ!ってことにはならないよね。WebとかだとJava以外にJSPだったりJSがいっぱいあって結局画面カチカチの試験はやることになる。画面カチカチするんだったら何のためのテスト何だろ。だって画面カチカチで動けばいいんだから、いらないジャン!そんなの!

まとめ

いやー、とりあえず思いつくのは、このくらいかなぁ。なんか言いたい放題言ってすっきりした。

JUnitに対して、批判を言いまくったけどバッチアプリだったり、ツールだったりフレームワークに関しては、間違いなくテストケースを作ったほうが良い。後から再帰試験やるの超楽になる。こいつらについては、テストケースを作るのは、大賛成!

でもWeb系とかだと、JUnitだけだとあくまでJavaの試験しか出来ないし、工数めっちゃ増えるし、仕変とか機能追加のとき作業増えるし
必ずしも作るべきだとは思わない。長年使う予定のシステムで最初に作った人たちがいなくなったりするようなところだと作ったほうがいいかなぁ、とか思ったんだけど、それだけ時間が経っていると結局コードだけでなく、テストケースも読めなくなっているから必ずしもあった方が良いとは言えない。ぼくが昔経験したプロジェクトで、JUnitはあるんだけど、もはや何千行とかに育っちゃって。読めないし、とりあえず妥当かどうかいまいちわからないけどカバレッジ通して、グリーンを目指せみたいなところがあった。

ぼくの中で最近出しつつ結論としては、やっぱWeb系の場合は、JUnitを作るより、Seleniumとか画面とセットで試験できる回帰試験ツールを使うべきだという結論に達しつつある。そうすれば、JUnitをグリーンにした後、画面カチカチする必要もないし。本来不要な試験も作る必要もないし。実際にやったことないけど確かSelenium使ってコードのカバレッジも測れたりするよね。すごい面倒だった気がするけど。

そうすれば、画面カチカチを自動化できて、不要なコードが少なくなって、カバレッジも測れる。はやりのTDDも出来るし。
これってエブリバディハッピーかも。

オブラブでも宣伝してたこの本を読んでみることにする

xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))

xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))

追記
再帰試験は間違いらしいので、回帰試験に修正しました。ご指摘ありがとうございます。