UIのテストは間接的に行う
そもそも UI のテスト駆動開発は難しいと言われています。数値や文字列が出力結果となるような他のプログラムと違って、UI はグラフィカルな変化が出力結果となるため、自動化テストにおけるアサーションを書きにくいからです。といっても、確認する方法がないわけではありません。クライアントサイドJavascriptにおいて、画面上の位置、背景の色、幅、高さ、透明度など、見た目を構成する要素の多くはCSSプロパティとして取得可能です。
直接見た目が正しいかを確認できなくても、これらCSSプロパティを通じて間接的に確認することができます。自動化テストのアサーションもCSSプロパティの値を対象に行えばよいでしょう。
また、クラスを付与・削除することによってCSSの適用範囲を変えて視覚的効果を実現する場合もあります。その場合はクラスの存在の有無を確認すればよいでしょう。
ではそれでテスト駆動で開発がスタートできるかというと、そうは問屋が卸しません。
外部ライブラリがJavascriptのテスト駆動開発を困難にする
Javascript のテスト駆動開発を困難にしているもう1つの原因は外部ライブラリです。 時間と労力の節約のため、先人の知恵を用いるのは有効な方法です。jQueryやその上で動くプラグイン等を始めとして先人の知恵の結晶であるライブラリが数多く存在します。しかしながら、テスト駆動開発においては「得られる結果を先に決める」ことが重要になるため、外部ライブラリはその点で不利です。UI 上で、ある効果を実現したいと思った時、採用することにした外部ライブラリがどのCSSプロパティの値をどう変化させるのかコーディング前に正確に把握することは一般的に困難です。ライブラリのAPIドキュメントを読んでもわからない場合が多いです。この状態ではテストを先に書くことができません。テストファーストで開発を進める最初の1歩が難しいのです。
「擬似」テスト駆動開発による解決策
そこで、本来のテスト駆動開発の流儀からは外れますが、まず目的の効果を部分的に得られる段階まで、テスト無しで実装を行なってしまいます。 これを「試験的な実装」と呼ぶことにします。そして、試験的な実装がどのようにCSSプロパティやクラスを変化させるか分かったら、それらの変化を自動化テストのアサーションとして記述します。ここで書くテストは、試験的な実装を全てカバーするようにします。そうすることでテストコードを伴わない実装をなくします。この段階でテストは全てグリーンです。
次に、テストコードを本来満たすべき仕様に合わせて変更します。試験的な実装を行ったおかげでCSSプロパティやクラスの変化の仕方はわかっているはずですので、書くべき自動化テストコードがわかるはずです。もしまだ分からないのなら、分かるようになるまで試験的な実装を進めて、そのぶんテストコードを書き足してから、上記作業を行います。
この時点でテスト結果はレッドです。ここから先は、通常のテスト駆動開発になります。レッド→グリーン→リファクタリングのサイクルを繰り返していきます。
開発を進めていくと、またテストファーストが難しい状態になるかもしれません。その際には再度試験的な実装を行い、試験的な実装を全てカバーするテストを書いてグリーンとし、そのテストを本来の仕様に合わせてレッドにします。そこから再びレッド→グリーン→リファクタリングのサイクルをスタートします。
このように、完全にテストファーストではありませんが、試験的な実装をうまく使うことで擬似的にテスト駆動開発を行うことができます。
まとめ
- UI 開発では視覚的効果を直接自動化テストで確認するのは困難だが、クライアントサイドJavascriptにおいてはCSSプロパティや クラスの変化を確認することで間接的にテスト可能。
- 「テスト無しの試験的な実装 → グリーンなテスト付きの試験的な実装 → 本来の仕様に変更しレッドとなったテスト」というプロセスを最初及び適宜途中に挟むことによって、擬似的にテスト駆動開発を行う。