機能テストの自動化に向けて

前回は、ツールを使っても機能テストを自動化するハードルは低くないですよ、ということを書きました。
残念ながら、高いお金を払って購入したテストツールもスケジュールが間に合わない現場の品質担保の救世主にはなりえません。やっぱりロジック部分の単体テストレベルはおとなしくxUnitを書いた方が早いでしょう。*1
ですが、機能テストの自動化に成功して、ViewやController部分がデグレった箇所を検知してくれるようになれば開発現場のモチベーションは上がるでしょう。
では、機能テストの自動化には、何を準備すればいいでしょうか?私の経験と妄想から、いくつか述べてみようかと思います。

動的な要素を固定にできる仕組み

外部パラメータで処理がスタブ化できれば、いつテストを実施しても結果は等しくなります。例えば、システム日付はテスト実行時毎に変わってしまうのですが、JVMのパラメータやプロパティファイルの設定値によって自動テスト用に固定日付を返すように仕込んでおけば、動的に変更することもなくなるわけです。
もちろん、アプリケーションでシステム日付を取得する時には思い思いにnew Date() とかSystem.currentTimeMillis()等を使用するのではなく、共通のユーティリティを使用するように徹底する必要があります。
また、SQL文の中でシステム日付を直接使用せず、パラメータとして設定するようにしなければなりません。
外部システムへの接続は「デバッグモード」を作成することで、「通信したつもり」で固定値を返すスタブを呼び、外部システムと実際にやりとりしなくても処理が続けられるようにします。
テストパターンを増やそうと思うとスタブとして値を返すパターンを作りこむ必要があるので、どこまで自動化すれば良いか判断が必要になります。*2

クライアントのシステム時刻をJavaScriptでごにょごにょ・・・なんて機能はやりづらいですね。クライアント側の機能においてもテストの為の固定値モードを用意するかは悩ましい所です。

この辺りの仕組みは、実装の段階で仕込んでおく必要があります。実装が終わってから上記のような仕組みの対応をしてもらうには、現場のモチベーションが下がること必至なので、事前にプロジェクト内で説明をして、合意を取っておく必要があるでしょう。


テストする時にシステム日付を変更してテストを実行することも考えられますが、テストを実行する為の手順の一つとして残さなければならないのがネックではあります。
(強引かもしれませんが、ある意味確実かもしれません)

機能テスト用のDBスキーマ/APサーバ

まぁ、これはテストが失敗した時=テストシナリオが通らなくなった時と把握したいからです。他の人がいじってて、テストが通らなかったということを起こさないようにする為です。ライセンスが許すなら、仮想化で何とでもなるでしょう。

テストスクリプトの番人

テストスクリプトを記録した時には正しかった振る舞いも、正しくなくなる時が来るかもしれません。
その際にはシステムの変更と共に、テストスクリプトの変更が必要になってきます。
仕様変更で、テスト用のデータパターンも追加する、となると、
テストスクリプトのメンテナンスもバカになりません。

効率を考えると

テストスクリプトの番人=テストツールの理解者=システムの仕様を把握してる人(テストケースを考えられる人)

が一番良いのですが・・・。

効率の良いテストスクリプト

全ての機能テストシナリオを自動テスト対象すると、コストが半端なくかかります。ある程度割り切って、ビジネスロジックのテストはxUnitで。画面遷移に絡む箇所のみ機能テストの自動化を行うくらいの気持ちでいいかもしれません。
検索条件に合致する一覧を表示する機能のテストでは、

  • 抽出条件に合致するデータが取得できているか、ソートは正しいか、はxUnitで。
  • 機能テストの方では、一覧が出ていること程度の確認でよいかもしれません

View側で見せるデータを加工している場合は機能テスト側に含める必要はあると思います

テストスクリプトを取るタイミング

まさに開発途中の時にテストスクリプトを取ったとしても、仕様変更が発生してしまうかもしれません*3

単体テストがある程度終わり、ユーザにざっくりと確認も取れた時に取る
デグレ検知/ミドルウェア変更時/ブラウザ変更時の為のテストスクリプト
画面の単体テスト
validationや入力項目の多い画面のテスト。可能であれば、せっかく取ったスクリプトを上の奴に組み込めれば尚良しです。

まとめ

例えば受託開発の場合、上記の取り組みは開発側がノーコストで行うわけにはいかないでしょうから、開発費に上乗せしなければなりません。機能テストの自動化がなされていれば改修時には回帰テスト分のテスト工数は減りますが、改修によるテストスクリプトのメンテナンスコストもかかるので開発費に上乗せしなければなりません。

回帰テストを実施するコスト >> 機能テストを自動化するコスト

が明らかであれば異議はないでしょうが、それにコストを払うのであれば新しい機能を2つくらい実装してもらった方が良いと思われることも多いのではないでしょうか?「品質を下げないこと」に対する投資への理解が得られないと認めてもらうのに時間がかかるかもしれません。これが自社で使用するシステムやサービスの開発だった場合は話が変わってくるんでしょうけどね。


でも、これだけ前準備をしても簡単にはいかないでしょうね。xUnitを実行するように、気軽に実行できないのが一番のネックです。やっぱりUI部分のテストは難しいです。
xUnitやるのが当たり前という流れに乗って、機能テスト自動化も一緒に盛り上がっていけば良いなぁ、と。もっと賢い人たちが本気で考えれば良いアイディアが出ると思うんだけどな。

*1:ビジネスロジックデバッグ実行して動作確認をするくらいの気持ちで、xUnitのテストクラス書いて実行してすれば、そんなに手間はかからないと思います

*2:時間は有限ですから

*3:テストスクリプトを取ったから仕変を凍結、というわけにもいかないでしょうから