X-Designer 再現 を使用したテスト

X-Designer 再現 を使用したテスト


X-Designer 再現機能は簡単に使用できて移植性のある、強力なウィジェットベースのテストツールです。 X-Designer がサポートするすべてのプラットフォームに対して、テストツールとして使用できます。

ウィジェットベースのテストの役割

ほとんどの Motif/Xt プログラミングでは、Motif ウィジェットを再利用し、X ツールキットを利用しています。 X-Designer 再現テストはテスト動作の制御とテストが成功したかどうかの判定の両方を行うために、Xt ウィジェット階層を主に使用します。

注意する点は、ウィジェット自体が正しいかどうかを調べているのではない、ということです。 X-Designer 再現機能では、ユーザーがアプリケーション内のウィジェットに対して行なったアクションによって、希望する結果が得られたかどうかだけを調べます。


注 - このテスト上のテクニックおよび方法は、テストの「腐敗」に対して非常に高い抵抗力があります。使用するディスプレイのサイズ、形状、品質とは関係なくテスト結果は同じになる必要があります。アプリケーション自体が変更された場合以外は、テストを追加または更新する必要はありません。また、もちろんこれらのテストは、テスト担当者に報告されていない変更があればすぐに検出します。

すべてのテストをこのように自動化できるわけではありません。アプリケーションが正しく表示されているかどうか、また (描画領域内などで) グラフィックのプログラミングが動作しているかどうかを常に目で確認する必要があります。ただし、ウィジェットベースのテスト方法を使用すると、アプリケーションの必要な部分だけに集中することができます。

テストの方法

これまでの経験から、テストスクリプトを作成する方法には、以下の 3 つの段階があります。

すでに記録したスクリプトの記録および再生

ユーザーアクションが記録されたとおり正確に再生されているかどうかを調べるには、この方法が最も簡単です。ただし、スクリプトが非常に大きくなり、保守が困難になる場合があります。また、テストのどの部分が失敗したかを特定することが難しい場合もあります。特に、アプリケーションに変更が加わると、スクリプト全体を再度記録しなければなりません。

スクリプトの細分化

ここでは、大規模なスクリプトを小さく独立したスクリプトに分割し、各スクリプトでアプリケーションが識別可能な部分をテスト実行します。プリプロセッサ (m4 または cpp など) または使い慣れたプログラミング言語を使用して、細分化された各スクリプトを展開することができます。この方法で、以下のようなスクリプトを構築することができます。

	StartApplication()
	OpenFile(foo.c)
	CloseApplication()

次に、プリプロセッサ、インタプリタ、コンパイラのうちのいずれかがこれらの細分化スクリプトを完全な X-Designer 再現コマンド群に変換します。

この簡単な方法によって「段階的な」プログラミングは必要なくなり、さらに、テストスクリプトも管理が非常に簡単になります。

テストを表現するために使用する言語は、注意して選択してください。主な選択基準は、次のとおりです。

このためには、Java や Python などのクラスベースの言語が最適です。それ以外の有力候補としては、Lisp や Prolog などの記号処理向けのモデル化言語があります。m4 などのプリプロセッサ、または C プリプロセッサでも高速に処理することができます。

または、アプリケーションが使用する言語でモデルを構築してもよいでしょう。こうすると、ソフトウェアを移植する場合に常に使用することができます。目安としては、一連のテストを設計しているのではなくプログラムを記述しているように感じたら、必ず他により簡単な方法があるということです。

このテスト方法は、小規模から中規模までの大部分のアプリケーションに適用できます。しかし、大規模アプリケーション ( X-Designer がその一例) の場合は、細分化にも次のような限界があります。

次に、これらの問題を解決する方法を説明します。

データ駆動型テスト

これまで X-Designer 用のテストを計画してきた経験から、テストを記述する最も対費用効果の高い方法は、各ダイアログの記述を用意してその記述をテストで使用することです。以下に示す「カラー」ダイアログが記述された例について考えてみます。

    ColorDialog.shell       = my_color_shell
    ColorDialog.helpbutton  = color_help
    ColorDialog.applybutton = color_apply
    ColorDialog.quit        = color_quit

テストする理由とは関係なく、このダイアログがテストで必要になるたびに、これらの記述を使用することができます。次にその例を示します。

	Open(ColorDialog)
	CheckHelpFor(ColorDialog)
	Close(ColorDialog)

上記の各関数は汎用関数で、記述したどのダイアログにも適用することができます。

以下に、Close の定義を示します。

  #define Close(dialog)
    in dialog.shell
      push dialog.quit
  #endif    

このテクニックを使用すると、インタフェースの記述とその記述を使用するアクションを分離することができます。また、インタフェースに変更を加えても、関連するデータ記述に変更を加える必要があるだけで、テストスクリプトは変更なくそのままです。新規ダイアログをアプリケーションに追加する際は、その記述およびダイアログで実行される非標準操作を作成するだけで十分です。

このような方法の最大の利点は、記述が簡単で明確であること、また、デザイン自体に非常に近いため、テストと製品開発の同期をとることで、確実で簡単なテストが実行可能であることです。

テストの成功/失敗の判定

よいテストとは、アプリケーションで調べる対象部分を分離するよう設計されたテストです。アプリケーションが停止しなければそのテストは成功です。それ以外の場合は失敗です。

自動再生それ自体がテストの最小形式です。1 個のユーザーアクションに対して起こり得る 1 つの結果をテストするという最小単位のテストであるためです。一連の動作がエラーなしで再生されると、予想した内容が実際に行われたということになります。

ファイルを開くというアクションを考えてみます。最小形式のテストでは、予測される結果は、ファイルが開かれ、すべての処理が正常に行われることです。ただし、このテストは決して完全ではありません。以下のような別の結果も考慮する必要があります。

テスト用スクリプトでの制御フローおよび式の使用

最も簡単なテストは、アプリケーションでの一連のアクションを記録し、次にそのスクリプトを再生してそれらのアクションを複製することです。スクリプトが正常に実行されるとアプリケーションには信頼性が得られますが、基本スクリプトの機能を増やすために X-Designer 再現機能によって提供される制御フローおよび式の追加コマンドを利用すると、さらに信頼度を高めることができます。これらのコマンドを使用すると、各種ディスプレイへの対応、ウィジェットのリソース設定の検査、メッセージ出力などを行うことができます。

アプリケーションをモノクロディスプレイで実行している場合はメッセージが表示されますが、フルカラーディスプレイで実行している場合はメッセージが表示されない、という場合を考えてみます。

もちろん、ディスプレイごとの個別テストは行う必要はありません。代わりに、メッセージを表示したい位置にコマンドを挿入し、これらのコマンドを以下のように if 文で囲みます。

if !IsPseudoColor
  message Non PseudoColor display
  in warning_popup
  push warning.OK
endif

これと同じ検査処理は、使用しているディスプレイのハードウェアやウィンドウマネージャとは関係なく行われします。

また、アプリケーションのダイアログのサイズも重要です。2 つのダイアログを同時に表示する場合は、あるディスプレイでは両方とも完全に表示され、別のディスプレイでは重なりあって表示され、3 番目のディスプレイでは一方のダイアログの上に別のダイアログが置かれます。この結果、アプリケーションの中のあるモードの警告メッセージがメインダイアログの下に隠れてしまい、アプリケーションがロックして見えることがあります。

以下のテストスクリプトの一部で、このような問題の解決方法を説明します。

if !IsVisible(open_file_dialog)
  error The Open File dialog is off screen
endif

アプリケーションが各種ディスプレイ上で異なる動作をする場合は、テストもこれに対応するように作成する必要があります。たとえば、ユーザーにディスプレイの品質が下がることを通知する警告ダイアログがアプリケーションから表示される場合があります。

今度は、オプションメニューからのオプションの選択について考えてみます。標準スクリプトが確実に選択を行うので、よいテストスクリプトの場合は、選択が行われたかどうかを検査します。

以下の例で、 X-Designer の「コード生成」ダイアログで「言語」オプションが予想された値に設定されたかどうかをテストする方法を示します。

  if !languageOption->menuHistory:'cppButton'
    message FAIL: Language option error.
    printres languageOption->menuHistory
    message expected cppButton
  endif

テスト失敗時の対処

テストに失敗した場合にとる方法は、次の 3 つがあります。

それぞれの処理は、特定の コマンド行オプションに対応します。

失敗を処理するには、自分のスクリプト内にその処理を作成することが最善の方法です。条件文を使用して、失敗時には正しいアクション (メッセージを出力するなど) をとってください。

上記以外で、テスト失敗の特定に役立つのが -v コマンド行オプションです。このオプションを使用すると、スクリプトからのコマンドは実行されたとおりに標準出力に表示されます。問題点を特定したら、スクリプトをさらに小さくして再度テストします。今度は (任意のデバッガとともに) このスクリプトを使用して問題点を識別します。また、バグが修正されていることを証明するために、一連の回帰テストにこのオプションを追加することもできます。

関連項目: