Cucumberは偉かった

Cucumberを初めて見た人はこんな違和感を感じるんじゃないかと思います。

なんだこれ。変なDSL入れるより、直接Rubyプログラムを書いちゃう方が楽じゃん。便利じゃん。速いじゃん。

僕もそう思っていました。

そう思ったプログラマは、Cucumberを使わずにTestUnitでテストを書きます。変なDSLを覚える必要も無ければ、書く必要もありません。幸せな日々。ん?ボタンをタップするコードを3回書いてるな?よしメソッドにしよう!TableViewの内容のテスト?メソッドにしよう!

そしてある日気づきます。Cucumberじゃん、これ……しかも、Rubyプログラムがそのままなので読みにくい。一体どこで間違えたのでしょう?

CucumberでテストしたいのはUIです。Cucumberのターゲットは受け入れテストなので、最終的な成果物のテストが必要になります。最終的な成果物は実際にユーザーが使うもののことが多いでしょう。従って、CucumberでテストするのはUIの挙動になります。ここに間違いの元があります。

Rspecでテストするコードの断片は、UIではありません。プログラムです。プログラムなのですから、当然論理的な整合性を重視して設計されますし、実装されます。適度な抽象化が施され、柔軟性と性能が問題となります。過度に密接に結合しているコンポーネントはないか確認をしましょう。おや、このモジュールはちょっと密結合すぎるんじゃないか?これじゃあテストが大変じゃないか!つまり、テストの容易性というのはプログラムの設計においてかなり重要な観点として扱って問題がありません。

UIは違います。テストの容易性は全く意味が無くて、ユーザーにとって使いやすいかどうかだけが意味を持ちます。つまり、普通にテストするのとは全く観点が違うのです。

Cucumberで記述されるテストでは、シナリオに従ってひたすら1ステップずつの操作を愚直に積み重ねていきます。データのセットアップをして、なにかの操作をして、その結果をテストして、次の操作をして、その結果をテストして……抽象度を上げることはとても難しいのです。むしろ、後から読んだときの理解のしやすさを考えると、つまりテストしたい対象の操作とテストとの距離を考えると、下手に抽象化しないほうが良いと言えます。

ループはいりません。ブロックもいりません。引数くらいはあったら良いと思います。多少不格好でも、自然言語で操作の内容が書いてある方が良いとすら思えてきます。

正しかったのはCucumberでした。