テスト設計とモデル
比較における情報の最適な抽象度は「テスト設計」のフェーズで考えます。テスト設計では、テストオートメーター[3]は改めて、自分がやろうとしている自動テストがどんな責務を果たしているかを意識しなければなりません。
たとえば、Selenium WebDriverとJUnitを組み合わせた自動化ツールは、Webブラウザへ行った入力や操作の結果として得られる実行結果を、期待結果と比較します。その比較がパスした場合、画面は正しく表示され、振る舞いも正しいと「みなし」ます。言い換えると、この場合のテストの責務は、正しい表示情報がWebブラウザに戻っているかどうかを、表示結果のOK/NGで判断することです。これは、MVCやMVVMにおけるViewとController、もしくはView Modelとのインターフェースと同じ抽象度で情報を取り扱っていることと同等ととらえてよいかと思います(図2)。
![図2:MVCおよびMVVMの例](http://cz-cdn.shoeisha.jp/static/images/article/8807/8807_02.png)
もちろん、Seleniumのモデルはこれらとは違います。WebDriverはあくまでもブラウザに対する入出力のドライバです。ですが、WebDriverによりブラウザへの入力やテスト実行後の比較が楽になり、Webアプリケーションに対する自動テストが画期的に開発しやすくなりました(図3)。この事実から、Viewの手前でテスト自動化をしてしまうことが、テスト自動化を容易にするカギになると分かります[4]。
![図3:Seleniumの例](http://cz-cdn.shoeisha.jp/static/images/article/8807/8807_03.png)
一方で、View自身のテストを行い、実際に正しく表示されるか、振る舞うかのテストを行う必要があるかもしれません。幸いにして、この例ではViewにあたるのが一般のWebブラウザなので、網羅的にテストする必要はないかもしれませんが、たとえば、ウィンドウを縮小拡大したときに画面が崩れたりしないかのチェックを目視で行うなど、ある条件でテストをしておく必要があるかもしれません。
また、必要に応じて、ビットマップの比較が必要な場合もあります。たとえば、ゲームのテストにおいて、画面上にあるはずのビットマップの要素(ゲームのキャライメージなど)をチェックしなければならない場合などです。
[3] テスト自動化の仕組みを構築・保守するエンジニア。
[4] 実際の自動テストでは、Maven、Subversion、Jenkinsなどのツールを併用してCI(継続的インテグレーション)の環境を構成していきます。
テスト計画と比較
テスト計画というと、管理的な話であまり面白くないように感じる人もいるかもしれません。しかし、テスト自動化をしたたかにやっていくためには、テスト計画は欠かせません。
計画といっても、いきなりガントチャートを書いたりはしません。テスト自動化における計画の主役は「テスト戦略」と「テストスコープ」です。これらを考えるのはテストマネージャやテストエンジニアのリーダーの役割ですが、テスト自動化を一番理解しているテストオートメーターにも参加してもらいたいと思います。
自動化するものとしないもの
繰り返して実行することがあり、その繰り返しに意味があるテストに限り、自動化する価値があります。
テスト自動化には、テストスクリプトを開発する(デバッグも含む)期間が必要です。たとえば、回帰テストの自動化を考えたとき、ソフトウェアの開発期間自体が短いと、テストを繰り返し実行できないかもしれません。言い方を変えると、テスト戦略として回帰テストを自動化すると考えるときは、ソフトウェアライフサイクルとテスト自動化の作業のバランスを考える必要があるということです。
一方で、発生頻度が低い障害を再現したり、その効果確認をする場合には、ある条件やシーケンスを正確に繰り返す自動テストは有効です。
テスト計画において、テストスコープは「何をテストして、何をテストしないか」を意味しますが、テスト自動化においては「何を自動化し、何を自動化しないか」を意味します。さらに、そこには「何は自動化できて、何は自動できないか」という実現可能性も入ります。実現可能性はテスト設計と絡み、試行錯誤しながら確認していくことになります。
テスト自動化の実現可能性は、テスト対象ソフトウェアの作りやモデルと関係しますし、人的リソースや自動化システムを構成するソフトウェア、ハードウェアの機材リソース、ツールなども関係します。また、それらを確保するか、投資するかはマネージャと話し合って決めることになるでしょう。そのために「このようなテスト要求におけるこの自動テストには、この機材とツールが必要で、このくらいの開発工数と保守コストがかかる」ということを説明できるように準備しておく必要があります。
説明の準備に適任なのはテストオートメーターでしょう。テストオートメーターは、ソフトウェアのテスト自動化のプロです。与えられたテスト要求から、自動化すべきかどうか、その要求に最適な自動化の手段は何か、必要なリソースや工数はどのくらいかが一番よく分かるはずです。
テストオートメーターは、テストマネージャやテストエンジニアとよく議論しながら、テストをするところとしないところ、手動テストでやるところと自動テストでやるところなど、テストの責務を1つ1つ決めていきます。それを決める背景となるのがテスト戦略です。テスト戦略は、そのプロジェクトのリスク分析結果から影響を受けます。
ロバストとセンシティブ、自動化の戦略
【訂正とお詫び】
本稿におきまして「ロバスト」と「センシティブ」の表記が逆になっておりました。比較が厳密なことをセンシティブ、比較が甘いことをロバストというのが正しい説明です。訂正してお詫びいたします。
本書の第4章では「テストの感度」について触れられています。テストの感度とは、実行結果と期待結果とを比較した場合のマッチ(一致)したと判断される度合いをいい、本書では比較が厳密なことをセンシティブ、比較が甘い(比較条件が緩かったり幅がある)ことをロバスト[5]と表現しています。感度は、センシティブであれば低い(マッチしにくいがピンポイント)、ロバストであれば高い(マッチしやすいがラフ)となります。
ゲームのテストで、画面上にあるビットマップの要素(たとえばゲームのキャラクタ)をチェックするとしましょう。センシティブなテストでは、そのキャラクタをビット単位で厳密に比較します。そのため、そのキャラクタを正確に特定して検出できますが、ビット単位でちょっとでも違えばマッチ(実行結果と期待結果が一致)しません。一方、ロバストなテストでは、比較が甘いため、ビット単位の値がずれたりしてもマッチします。これにより、たとえば解像度が多少違っても検出することができる一方で、違うイメージにマッチして誤検出をするリスクもあります。
通常は、センシティブなテストとロバストなテストを組み合わせて使います。ゲームキャラクタをチェックする例でいえば、最初からセンシティブなテストを行うとなかなかマッチせずテストが進みません。そこで、まずロバストなテストを行い、実行結果が最終的な期待結果にある程度近づいてからセンシティブなテストを行うという戦略が考えられます。
[5] ロバスト(robust)というのは非常に分かりにくい言葉で、原著者のDorothy Graham氏に意味を確認したところ、言い換えとして「specified」という返事がありました(これも分かりにくいのですが)。
自動比較が難しいテスト
実行は自動化できても、自動比較が難しい場合があります。そのようなケースにはUIの官能テストがあります。画面のデザインの良し悪し、動作の軽快さ、理解しやすさ、操作の動線に無駄や混乱はないか、振る舞いに一貫性があるか、操作の予測性が高いかなどのテストです。
また、画質が悪い、音質が悪いといった感覚的な要素も自動比較は難しく、手動テストで行うことが賢明でしょう。
しかし、あるタイミングで画像が真っ暗になる、ノイズや想定外の絵が入る、音声にノイズが入る、音が消えるといった障害を解決する場合は話は違います。そうした障害が発生するタイミング・条件で再現テストや修正後の確認テスト(確かに治ったか、変更があったときに再発しないかなど)、回帰テストが必要になることがあります。
とはいえ、動画のブラックアウトやノイズ、音声の途切れやノイズを自動比較するのは簡単ではありません。まず多種多様なノイズの性質を理解する必要があり、その上で自動比較する仕組みを開発しなければならないからです。
一方で、それを人間がやるのも大変です。一瞬しか見えない/聞こえないノイズを拾うために、何時間も集中して作業することはできません。時間も回数も稼げませんから、チェックから漏れる確率も高くなります。
このように、自動比較はテストの実現可能性のカギとになることもあります。テスト設計では自動比較の方法を選択しますが、逆に自動比較の実現可能性がテスト設計の制約条件になることもあるのです。時には、自動比較の仕組みを独自に開発する必要が出てくるかもしれません.その時、その実現可能性をコストや時間も含めて吟味し、それでもやるか代替案で妥協するかは、リスクや製品戦略から判断される品質要求で決めることになるでしょう。
自動テストの保守性
自動テストを進めていくと、テストスクリプトがどんどん増え、自動テストシステムは肥大化していきます。さらに、テスト対象のソフトウェアがバージョンアップや派生を重ねてしていくと、そのテストスクリプトの変更・追加や保守コストが膨大になってきます。そのため、自動テストにおいても保守性を考慮する必要があります[6]。
自動化のテストケースの究極は、「テストケースを変更しなくても、後のバージョンアップや派生モデルにも使い続けられるようにすることだ」といわれています。新しい条件がGUIに加わっても、その条件が効いていない場合をデフォルトとしておけば、その条件が加わる前のテストケースを使うことができます。この工夫は、開発者と協力して行わなければなりません。
自動テストの仕組みを構築し保守する役割であるテストオートメーターは、自動テストが進むのに合わせて、テストの保守性との戦いを繰り広げていくことになります。その工夫を怠ると、膨大なテストスクリプトやテストデータ、期待結果のデータの変更の嵐となり、デバッグ、保守、構成管理に時間を費やすことになります。これでは、自動テストの本来の目的である効率化から遠ざかってしまいます。
[6] 本書の第12章ではSeleniumを例に、テストの保守性について説明しています。
自動テストを行うことの妥当性
いきなりですがクイズです。次に挙げるのは、テスト自動化の一連のプロセスです。この中で、ソフトウェアのソースコード中のバグが最もたくさん見つかるプロセスはどこだと思いますか?
- テストの計画
- テストの分析/設計
- 自動テストの開発
- テストの実施
- テストの報告
筆者がこれまでに聞いた話を総合すると、「3. 自動テストの開発」で最もたくさんのバグが見つかるようです。テストスクリプトのバグを見つけるのと同時に、ソースコードのバグも見つけるのです。そして、テストスクリプトのバグを大方取り終わったころには、ソースコードのバグのほとんどが見つかってしまうのです。
これは、自動テストを回帰テストと位置付けて開発するときによく起きます。回帰テストですから何回も同じテストを行うので、テスト自動化に最も適しています。
回帰テストで発見を期待されるのはデグレードです。しかし、回帰テストの開発時にソースコードのバグが大方出てしまうため、CIツール(継続的インテグレーションツール)が動いて回帰テストを実行しても、バグがほとんど出ないことがしばしばです。
こうした場合の自動テストは、投資の割にバグを発見していない(投資対効果が低い)ようにも見えます。そのため、「回帰テストの自動化は本当に効率を高めているのか」と疑問を持つ人が現れます。一方で、「これはデグレードのための保険である」と自動テストを擁護する人も出てきます。
こうした侃々諤々(かんかんがくがく)の議論を収めるためには、発見するバグの数や質に対する投資対効果を正しく吟味していく必要があります。リリース前にバグを発見し修正できたことの価値は、リリース後にバグが発覚したときに起こる信用の毀損や対応にかかるコストを上回るでしょう。それを見える化するのです。
また、回帰テストの開発では、手動で行ったテストを自動化(スクリプト化)することがよくあります。しかし、デグレードはソースコードの変更による影響の確認漏れから発生します。つまり、デグレードを防ぐには、変更が影響を及ぼす範囲を推定して、回帰テストのスクリプトを見直す作業が必要になります。
こうしたコストを鑑みた自動テストの投資対効果を明らかにするには、自動テストに対する「振り返り」が必要でしょう。振り返りにより、ツールの価格やテストスクリプトの作成工数、メンテナンス費用などをまとめ、投資に関わるステークホルダ(つまり上司やマネージャ)に報告します。
そのために、自動テスト実行の際はOK/NGの評価結果だけでなく、テストの内容、検出したバグ、デグレード発生の有無を記録しましょう。バグを放置したときのリスクインパクトも報告できると、費用対効果を認めてもらう材料になります。
さらに、費やした機材コストや工数なども記録できていれば、次に行う自動テストにかかる見積もりや計画、予算建てがしやすくなります。費用対効果は、テスタ自身の評価にもつながります。
自動テストエンジニア・テストオートメーターのやるべきこと
テストオートメーターという役割は、テストの自動化やテストの環境作り、テストスクリプトの作成ができるというだけでは務らないと思います。
そもそも、対象ソフトウェアのアーキテクチャが、テストを自動化できるほどのテスタビリティを持っていない場合、どんなにツールを知っていても手も足もでません。開発者は、開発の観点からそのドメインと要求によって最適なモデルを選ぶのであって、テスト自動化に有利なモデルを採用するとは限らないからです。
テストオートメーターは、効率的で有効な自動テストを行うために、開発者に対して、テスト自動化に有利なモデルを説明し、さらにそれが開発者にとっても非常にメリットのあることだと説いて、テスタビリティの高いアーキテクチャの採用を促す力を持つ必要があります。加えて、テスト自動化に必要な初期投資と保守投資をステークホルダに認めてもらうための説明能力も必要です。
これらは骨の折れることではありますが、自分のスキルを生かすためには必要なことです。ソフトウェア開発者と協力関係を築き、自動テストによって良いフィードバックを返すことができるようになれば、お互いの信頼関係が増し、さらなるチャレンジができるはずです。それこそ、テストオートメーター冥利に尽きるというものでしょう。