Selenium はオープンソースのプロジェクトですが、テスト時に発生する問題について簡単に調べられるドキュメントがありません。そのため、テスターが Selenium を使用して問題の調査を行おうとすると非常に時間がかかります。この記事では、2009年 6月にリリースされた Selenium 1.0 を使用して Web アプリケーションのテストを行う際の一般的な問題に対するベスト・プラクティスについて説明します。

Peng Cheng Yu, Software Testing Engineer, IBM

Peng YuPeng Yu は IBM China Development Lab のソフトウェア技術者です。彼はいくつかの世界的プロジェクトでテスト・リーダーを務めており、アジャイルなテスト、品質保証、テスト自動化の経験があります。



Zhang Chao Chao , Software Engineer, IBM

Chao Chao ZhangZhang Chao Chao は IBM China Development Lab のソフトウェア・テスト技術者です。彼女はアジャイルなテストとテスト自動化の経験があります。



2012年 1月 06日

はじめに

Selenium は、多くのプラットフォームにわたる Web ベースのアプリケーションに対してテストを自動化することでアジャイル開発をサポートする堅牢なツール・セットです。Selenium は軽量でオープンソースの自動化ツールであり、さまざまなプロジェクトに容易に組み込むことができ、さまざまなプログラミング言語をサポートしています (.NET、Perl、Python、Ruby、Java など)。


Selenium を使用して Ajax アプリケーションをテストする

Ajax (Asynchronous JavaScript and XML) は対話型の Web アプリケーションを作成するための Web 開発手法です。Ajax アプリケーションの特徴は、毎回ページ全体をロードするわけではない点です。ブラウザーは非同期でサーバーを呼び出してデータを取得し、現在のページの特定部分のみを更新します。Web ページの対話性、応答速度、ユーザビリティーを向上させるために Ajax アプリケーションを開発した場合、そのテストは通常のアプリケーションとは多少異なる方法で行わなければなければなりません。

テスターは Web ページ上で操作を行うことで検証を開始し、非同期の呼び出しが完了するのを待機します。呼び出しが完了すると、検証を継続することができます。この時点で、適切な待機時間はどの程度か、という問題が生じます。

ある待機時間の後に検証を再開する 1 つの方法は、単純にテスト・アプリケーションの中で一定時間停止する方法です。この方法はほとんどの場合に有効ですが、ネットワークのスループットが低い場合などの一部の状況では、指定時間だけ停止しても Ajax 呼び出しが完了せず、テスト・ケースが失敗してしまいます。その一方、停止時間が長すぎると、許容できないほどテストの実行に時間がかかるようになってしまいます。

Selenium を利用すると、もっと効率的な方法で待機の処理を行うことができます。1 つの方法は、com.thoughtworks.selenium.Wait クラスを使用し、ある 1 つの要素またはテキストがページ上に現れるのを待つか、ページ上から消えるのを待つ方法です。待機を終了する条件は until() 関数の中で定義することも、Wait クラスを継承して実装することもできます。リスト 1 は Wait クラスを使用するサンプル・コードを示しています。このコードは条件が満たされると待機を終了し、最大待機時間を超えるとタイムアウト例外を返します。

リスト 1. 要素またはテキストが現れるのを待つ
  Wait wait = new Wait() {
	public boolean until() {
	return selenium.isElementPresent(locator);
	// or selenium.isTextPresent(pattern);
	}
  };
  wait.wait("", timeoutInMilliseconds);

Selenium を利用したもう 1 つの方法は、Selenium に用意された waitForCondition 関数を使用し、この関数にパラメーターとして JavaScript スニペットを渡す方法です。Selenium はこの JavaScript に含まれる判定条件によって真が返されたことを検出すると、待機を終了します。待機の終了条件を何らかの要素またはテキストが表示された時点、あるいは表示されなくなった時点にすることもできます。JavaScript は Selenium.browser.getCurrentWindow() 関数によって取得されるアプリケーション・ウィンドウ内で実行することができます。リスト 2 はそのウィンドウの状態をチェックするサンプル・コードです。このコードは Firefox のみで動作します。

リスト 2. ウィンドウがレディー状態になるのを待つ
String script = "var my_window = selenium.browserbot.getCurrentWindow();" 
script += "var bool;";
  script += "var readyState = (my_window.document.readyState);";
  script += "if (readyState == 'complete'){";
  script += "bool = 'true';";
  script += "}";
  script += "bool;";
  selenium.waitForCondition(script, timeoutInMilliseconds);

Dojo アプリケーションをサポートする方法

Dojo は動的な Web インターフェースを作成するためによく使われる JavaScript ツール・キットです。Selenium を使用して Dojo アプリケーションをテストする上で重要な点は、Dojo ウィジェットを認識することと Dojo ウィジェットのアクションを記録することです。アプリケーション作成者が定義した Dojo ウィジェットは抽象的なレベルにあります。ページが実行されると、そのページが Dojo ウィジェットを基本的な HTML コードに変換します。Dojo によって自動生成される HTML コードは大量にあり、従って Dojo ウィジェットを認識するための処理は従来の HTML ウィジェットを認識する場合の処理と少し異なる可能性があります。

一方、Dojo ウィジェットのアクションを記録することに関しては、テキスト・フィールド、ボタン、チェックボックス、ラジオ・ボタンといった Dojo ウィジェットは、HTML ウィジェットの場合と同様の処理をすればよいかもしれませんが、コンボ・ボックスの場合や、日付セレクター、そして Dojo が提供するその他のウィジェットの場合は、特別な処理が必要になるかもしれません。

図 1. Dojo のコンボ・ボックス
スクリーン・ショットには、いくつかの選択肢を持つコンボ・ボックスが表示されています。

図 1 に示すコンボ・ボックスで選択されるアクションは、Selenium IDE を使用して記録します。下向き矢印をクリックするとドロップダウン・リストが表示されるので、ここでは 3 番目の項目である「Stack(SWG)」を選択します。この操作に対して記録されたスクリプトを図 2 に示します。

図 2. Selenium IDE によって記録されたスクリプト
スクリーン・ショットには、マウス・クリックなど、Selenium IDE によって記録された情報が表示されています。

場合によると、Selenium IDE によって 2 行目のスクリプトのみが生成されることがあります。その場合には、矢印ボタンをクリックするアクションを追加します。上記のスクリプトの場合、最初の行が再度実行されるとドロップダウン・リストが生成されるはずですが、実際には何も実行されません。さまざまな Dojo ウィジェットに対して click コマンドを実行しても、実際にクリック・アクションが実行されるわけではないのです。そこで、click(locator)clickAt(locator, coordString) に、または MouseDown(locator)MouseUp(locator) に変更します。

また、ドロップダウン・リスト用に待機時間を追加する必要があります。図 2 のスクリプトに示すように、ドロップダウン・リストから項目を選択するためのクリック・アクションは下向き矢印ボタンをクリックした直後に実行されます。しかしまだドロップダウン・リストは現れていないため、このアクションはおそらく失敗します。単純に pause コマンドを追加するか、あるいは waitFor コマンドを使用して項目要素が表示されるのを待ち、それに続いて次のコマンドを実行します。

Dojo のコンボ・ボックスで選択を行う操作を自動化するように変更したスクリプトを図 3 に示します。

図 3. Dojo のコンボ・ボックスで選択を行う操作を自動化するように変更した後の Selenium IDE スクリプト
スクリーン・ショットには、変更された clickAt コマンド、waitForElement コマンド、clickAt コマンドが表示されています。

Selenium RC のコードをリスト 3 に示します。

リスト 3. Dojo のコンボ・ボックスの選択動作を自動化する Selenium RC コード
  selenium.clickAt("//div[@id='widget_offeringType']/div/div",””);
  selenium.waitForCondition("selenium.isElementPresent(\"offeringType_popup2\")", "2000");
  selenium.clickAt("offeringType_popup2",””);
図 4. 日付セレクター
スクリーン・ショットには、日付セレクターとして、ひと月分が表示された通常のカレンダーが表示されています。

図 4 の日付セレクターの例の場合、実行されたアクションが Selenium IDE に記録されないかもしれません。そこでリスト 4 のような Selenium RC コードを作成します。

リスト 4. 選択を自動化する Selenium RC コード
//click on the date field by id you defined;
selenium.clickAt("dateBox",""); 
//wait for the drop down date box by id;
selenium.waitForCondition("selenium.isElementPresent(\"widget_dateBox_dropdown\")", \
"2000"); 
//click previous year 2008;
selenium.clickAt("//span[contains(@class,'dijitCalendarPreviousYear')]", "");
//click on the month increase; 
//previous month would contains  ‘dijitCalendarIncrease’.
selenium.clickAt("//img[contains(@class,'dijitCalendarIncrease')]","");
//click on the date such as 28 of current month; If you do not specify 
//the td with the attribute of current month class, it will click \
on the //first 28 of previous month;
selenium.click("//td[contains(@class,'dijitCalendarCurrentMonth')]/span[text()='28']");

例で示したように、単純に Selenium IDE で記録するだけでは Dojo アプリケーションをテストすることはできません。これらのスクリプトを実行しても、おそらくテストは成功しません。不足しているアクションがある場合や、実際にはアクションが動作しない場合があります。Selenium IDE でも Selenium RC でも問題なくスクリプトが実行されるように、スクリプトを調整する必要があります。Selenium は JavaScript を十分にサポートしているので、複雑な Dojo ウィジェットの場合には、runScript(String) 関数を使用する方法が考えられます。リスト 5 にコンボ・ボックスの選択をシミュレートする JavaScript の命令を示しています。

リスト 5. JavaScript の命令を実行してコンボ・ボックスを選択する
selenium.runScript("dijit.byId(\"offeringType\").setValue(\"Stack(SWG)");");

Ant を使用して Selenium のテストを作成する方法

Ant などの統合ツールは、Selenium サーバーを単独で起動せずに Selenium のテストを作成して円滑にテスト・ケースを実行するための手軽な手段です。Selenium によるテストを TestNG を使用して実行する場合には、TestNG の Ant タスクをリスト 6 のように定義します。リスト 6 で、classpath は TestNG.jar ファイルへのファイル・パスを意味します。

リスト 6. TestNG の Ant タスク
<taskdef resource="testngtasks" classpath="testng.jar"/>       

Ant タスクの主な目的は、サーバーを起動してテストを実行し、最後にサーバーを停止することです。リスト 7 の bulid.xml に定義されているように、これらのタスクは連続的に実行されます。

リスト 7. サーバーを起動してテスト・ケースを実行し、最後にサーバーを停止する Ant タスク
<target name="run_test" description="start,run and stop" depends="dist">
<parallel>
 <antcall target="start-server" /> 
<sequential>
 <echo taskname="waitfor" message="Waitforproxy server launch" /> 
 <waitfor maxwait="2" maxwaitunit="minute" checkevery="100">
 <http url="http://localhost:4444/selenium-server/driver/?cmd=testComplete" /> 
 </waitfor>
 <antcall target="runTestNG" /> 
 <antcall target="stop-server" /> 
 </sequential>
 </parallel>
 </target>

Selenium サーバーが問題なく起動したかどうかをテストするには、一定時間停止するよりも、waitfor タスクを使用した方が適切です。URL http://localhost:4444/selenium-server/driver/?cmd=testComplete にアクセスできる場合には、Selenium が問題なく起動したということです。リスト 7 の waitfor タスクは、100 ミリ秒ごとに localhost の Selenium サーバーにアクセスし、この起動が完了したことを示す URL が提供されたことが確認されるまで最長で 2 分、この確認を行い続けます。

start-server タスクの詳細の定義をリスト 8 に示します。Firefox のプロファイル・テンプレートの場所や他の引数は <arg> タグで指定することができます。

リスト 8. サーバーを起動するための Ant タスクの詳細
<target name="start-server">
<java jar="lib/selenium-server.jar" fork="true">
 <arg line="-firefoxProfileTemplate ${selenium}/profile/" /> 
 </java>
 </target>

runTestNG タスクの詳細の定義をリスト 9 に示します。testing タスクによく使われる属性には、outputDirxmlfileset などがあります。outputDir 属性は出力レポートの場所を設定するために使われます。xmlfileset 属性は起動用の XML ファイルを含めるために使われます。他のオプションに関しては TestNG の公式サイトを参照してください。

リスト 9. テスト・ケースを実行するための Ant タスク
<target name="runTestNG">
<testng outputDir="${testng.report.dir}" sourcedir="${build}" 
classpathref="run.cp" haltOnfailure="true">
 <xmlfileset dir="${build}" includes="testng.xml" /> 
 </testng>
 </target>

stop-server タスクの詳細はリスト 10 で定義されています。

リスト 10. Selenium サーバーを停止するための Ant タスク
<target name="stop-server">
 <get taskname="selenium-shutdown" 
src="http://localhost:4444/selenium-server/driver/?cmd=shutDown" ignoreerrors="true" /> 
 <echo taskname="selenium-shutdown" message=" Errors during shutdown are expected" /> 
 </target>

重要なタスクは上記のとおりです。これらのタスクをビルド・ファイルと組み合わせると、Ant と適切に統合されたテストを作成することができます。


HTTPS Web サイトのテストをサポートする方法

インターネットの情報セキュリティーがより一層重要視されるようになるにつれ、SSL 認証を使用する Web アプリケーションが多くなっています。Selenium IDE はデフォルトで HTTPS をサポートしていますが、Selenium RC はサポートしていません。HTTPS Web サイトをテストする場合、Internet Explorer (IE) と Firefox とでソリューションは異なります。

IE の場合、setup ディレクトリーの下にある SSL サポート・フォルダーに証明書をインストールします。使用しているバージョンが Selenium-RC 1.0 beta 2 よりも前の場合には *iehta 実行モードを使用し、Selenium-RC 1.0 beta 2 またはそれ以降の場合には *iexplore 実行モードを使用します。

HTTPS Web サイトのテスト中に下記のようなセキュリティー警告が表示された場合には、「View Certificate (証明書の表示)」をクリックし、その HTTPS Web サイトの証明書をインストールします。それでも警告が表示される場合には、次のように IE を構成してみてください。「Tool (ツール)」 > 「Internet Options (インターネット オプション)」 > 「Advanced (詳細設定)」の順に選択し、セキュリティー・カテゴリーの下にある「Warn about invalid site certificates (無効なサイト証明書について警告する)」と「Check for publisher's certificate revocation (発行元証明書の取り消しを確認する)」のチェックを外します。

図 5. HTTPS Web サイトをテストする場合のセキュリティー警告
スクリーン・ショットには、証明書に問題があることを警告する「Security Alert (セキュリティの警告)」ウィンドウが表示されています。

新しい Firefox プロファイルを作成する

Firefox の場合には、カスタマイズしたプロファイルを以下のステップに従って作成した後、サーバーを再起動します。

  1. 実行中の Firefox インスタンスをすべて閉じます。
  2. プロファイル・マネージャーを指定して Firefox を起動します ( firefox -ProfileManager)。
  3. 新しいプロファイルを作成します。そのプロファイルのディレクトリーを選択するように促されたら、ディレクトリーを選択します。そのディレクトリーをプロジェクト・フォルダーの中に配置します。
  4. そのプロファイルを選択して Firefox を実行します。
  5. テスト対象となる、自己署名の証明書を持つ HTTPS の URL にナビゲートします。証明書を受け入れるかどうか促されたら、受け入れます。するとそのプロファイルに例外が作成されます。
  6. ブラウザーを閉じます。
  7. Firefox のプロファイル・ディレクトリーに行きます。
  8. そのディレクトリーの中で、cert_override.txt ファイルと cert8.db ファイル以外のすべてのファイルを削除します。

Selenium はデフォルトで、Firefoxのインスタンスを起動すると新しいプロファイルを作成します。-firefoxProfileTemplate /path/to/profile/dir というパラメーターを指定してサーバーを起動すると、Selenium は (証明書の例外を含む) 部分的なプロファイルを基に新しいプロファイルを作成します。こうすることで、プロファイル全体を使用することによる余分な混乱を生じることなく、証明書の例外を提供することができます。Firefox を起動する場合の注意点として、Selenium RC 1.0 beta 2 またはそれ以降の場合は *firefox モードで起動し、Selenium RC 1.0 beta 2 よりも前のバージョンの場合は *chrome モードで起動する必要があります。

実行モードに関して言えば、*chrome*iehta は、Selenium RC の初期バージョンで HTTPS や、セキュリティー・ポップアップの処理をサポートするための実験的なモードでした。この 2 つの実行モードは安定化され、Selenium-RC 1.0 beta 2 からは *firefox*iexplore という実行モードになっています。使用する Selenium のバージョンに応じて使用する実行モードが異なるので注意してください。


ID プロパティーを使用せずに Web 要素を効果的に認識する方法

意味のある ID や名前を使用すると、要素の検索が効率的に行えて便利になり、テスト・ケースもわかりやすくなります。Selenium では、各要素 (特に動的要素) が意味のある一意の ID を持てるように、要素を認識するための手段が複数用意されています (XPath、DOM、CSS など)。

以下に示すのは、図 6 の動的な表の中で要素を検索するために 3 つの方法を使用する例です。この HTML コードをリスト 11 に示します。

図 6. 動的テーブルの例
スクリーン・ショットには、動的に作成された単純な表が表示されており、2 つの列の一方には編集するためのリンクが含まれています。
リスト 11. 表の最初の列の HTML コード
	<table id="test_table" border="1">
		<tbody>
        <tr>
            <td align="left">
                <div class="test_class">Test 1</div>
            </td>
            <td align="center" style="vertical-align: top;">
                <table id="AUTOGENBOOKMARK_4">
                    <tbody>
                        <tr>
                            <td align="center" style="vertical-align: top;">
                                <div>
                                  <img alt="supported" src="supported.png"/>
                                </div>
                            </td>
                            <td align="center" style="vertical-align: top;">
                                <div>
                                   <a href="test?name=test1">edit</a>
                                </div>
                            </td>
	…….

XPath は特別な ID や名前を使用せずに要素を検索するための単純な手段です。

  • ID や名前以外の属性がわかっている場合には、@attribute=value を使用して要素を直接検索することができます。
  • 属性値の特定部分のみがわかっている場合には、contains(attribute, value) を使用して要素を検索することができます。
  • 要素に何も属性が指定されていない場合には、その要素に最も近く、指定された属性を持つ親要素を Firebug で検索し、次にその親要素を出発点として XPath を使用して目的の要素を検索します。
表 1. 要素を検索するための XPath 式
検索対象の要素XPath 式
行 n の最初の列//table[@id='test_table']//tr[n]/td
行 n の画像//table[@id='test_table']//tr[n]//img
「Test 1」を編集するためのリンク//a[contains(@href,test1)]

表 1 は要素を検索するための XPath 式を示しています。Firebug を使用することで、XPath は要素と重複要素を検索することができます。Selenium IDE は、要素に ID も名前もない場合には XPath を採用します。XPath は記録されたスクリプトと一致する要素を検索する上で有効ですが、Web ページの構造に大きく依存するため、テスト・ケースがわかりにくくなり、保守にも手間がかかります。また、複数の複雑な XPath があるテスト・ケース (Internet Explorer 7 や Internet Explorer 8 の式など) の場合には、実行速度が遅くなりすぎる可能性があります。このような場合には、XPath の代わりに、要素を検索するためのもう 1 つの効率的な手段である DOM を使用するように変更します。

DOM は Document Object Model を省略した表現です。Selenium では JavaScript を使用して HTML の DOM をトラバースすることができます。JavaScript は柔軟であるため、セミコロンで区切った複数の命令を DOM 式に含めることや、命令の中で関数を定義することができます。

表 2. 要素を検索するための DOM 式
検索対象の要素DOM 式
行 n の最初の列dom=document.getElementById('test_table').rows[n-1].cells[0]
行 n の画像 dom=element=document.getElementById('test_table').rows[n-1].cells[1]; element.getElementsByTagName('IMG')[0]
「Test 1」を編集するためのリンク
dom=function test(){
var array=document.getElementsByTagName('a');
var element;for(var i=0; i<array.length; i++)
{if(array[i].attributes.getNamedItem("href").\
value.indexOf('test2')!=-1){element=array[i];break;}}return element}; test()

表 2 は要素を検索するための DOM 式を示しています。Firefox の場合も Internet Explorer の場合も、DOM による検索のパフォーマンスは優れています。DOM 式を構成するためには、JavaScript の知識がある程度必要です。複雑な要素の場合、DOM 式が長すぎて読みにくくなる場合があります (その一例として、表 2 の最後の行の DOM 式を見てください)。

CSS による検索を使用すると、CSS セレクターによって要素を選択することができます。HTML コードのスタイルが適切であれば、CSS による検索を効率的に利用することができます。CSS 式の例を表 3 に示します。

表 3. 要素を検索するための CSS 式
検索対象の要素CSS 式
行 n の最初の列css=#test_table .test_class:nth-child(n)
行 n の画像
css=#test_table  tr:nth-child(n) > td:nth-child(2) > 
table td:nth-child(1) > div >  img
「Test 1」を編集するためのリンクcss=a[href*='test2']

一般論として、使い慣れた検索式を選択するようにし、またスクリプトの構造に合った検索式を選択するようにします。実行する式が複数ある場合には、最も効率的な方法を使用して Web ページの要素を検索するようにします。


ポップアップ・ウィンドウの処理方法

一般的に、アクションは Selenium によって起動されたメイン・ウィンドウで実行されます。window.open 関数によって生成された新しいウィンドウでアクションを実行したい場合には、その新しいウィンドウにフォーカスを変更します。ポップアップ・ウィンドウでアクションを実行したら、フォーカスをメイン・ウィンドウに戻します。リスト 12 はポップアップ・ウィンドウの処理手順を定義しています。

リスト 12. ポップアップ・ウィンドウを処理するためのサンプル・コード
 //wait for the popup window with timeout;
selenium.waitForPopUp(windowname, timeout); 
//select the pop up window
selenium.selectWindow(popupWindowIdentifier);
//perform action on popup window and close the window;
.... 
//return to the main window use 'null' 
selenium.selectWindow(null);

windownamewindow.open 関数を呼び出すための 2 番目のパラメーターです。上記の popupwindowIdentifier はウィンドウ識別子であり、ウィンドウ識別子としては、ウィンドウ ID やウィンドウ名を指定したり、title=<ウィンドウのタイトル>、var=<JavaScript 変数> といった形式で指定したりすることができます。ポップアップ・ウィンドウの属性が実際に定義されているけれどもわからない場合は、getAllWindowIds()getAllWindowNames()、または getAttributeFromAllWindows() 関数を使用してポップアップ・ウィンドウの属性を取得します。

最新バージョンの Selenium RC 1.0.1 には、selectPopUp(String)deselectPopUp() などのメソッドが追加されています。1.0.1 よりも前のバージョンでは、これらのメソッドの関数は selectWindow(String) によって提供されています。

リスト 13. ポップアップ・ウィンドウを処理するためのポップアップ関数
 //wait for the popup window with timeout;
selenium.waitForPopUp(“”, timeout); 
//same as selenium.selectWindow
selenium.selectPopUp(“”);
//perform action on popup window and close the window;
.... 
//same as selenium.selectWindow(null);
selenium.deselectPopUp();

リスト 13 には、ポップアップ・ウィンドウを処理するための最も単純な方法が示されています。waitForPopUp 関数と selectPopUp 関数の最初のパラメーターは空のままで構いません。複数のウィンドウが同時にポップアップ表示される場合には、ウィンドウの属性を指定します。


ファイルのアップロード/ダウンロードのウィンドウの処理方法

Selenium は JavaScript を使用してアクションをシミュレートします。そのため、アップロード・ウィンドウやダウンロード・ウィンドウ、認証ウィンドウなどのブラウザー要素はサポートしていません。また、偶発的に表示されるポップアップ・ウィンドウについては、スキップするようにブラウザーを構成します。

図 7. セキュリティー情報のウィンドウ
このスクリーン・ショットにはセキュリティー情報のポップアップが表示されており、このページにセキュアな項目とセキュアではない項目の両方が含まれていることを示しています

図 7 のセキュリティー情報ウィンドウをスキップするためには、Internet Explorer の場合、「Tools (ツール)」 > 「Internet Options (インターネット オプション)」 > 「Security (セキュリティ)」 > 「Custom Level (レベルのカスタマイズ)」の順に選択し、「Display mixed content (混在したコンテンツを表示する)」という項目で「Enable (有効にする)」をクリックします。

Internet Explorer を構成することで偶発的なウィンドウがポップアップされるのを回避すると、テスト・ケースを実行する際に不要な処理を減らす、あるいはなくすことができます。ただし Firefox を構成する場合には、その構成を新しいプロファイルとして保存し、そのカスタマイズしたプロファイルを使用してサーバーを起動します。その理由は HTTPS Web サイトのテストを説明したセクションで触れたとおりです。

アップロード・ウィンドウやダウンロード・ウィンドウの場合には、ウィンドウをスキップするのではなく、ウィンドウを処理した方が適切です。Selenium の制約を避けるための 1 つの助言として、Java ロボット AutoIt を使用してファイルのアップロードとダウンロードの問題を処理する方法があります。AutoIt は Windows GUI の操作を自動化するために設計されており、ほとんどの Windows GUI を認識することができます。また、多くの API を提供している AutoIt は、容易に .exe ファイルに変換することができ、その .exe ファイルを直接実行したり、Java コードの中で呼び出したりすることができます。リスト 14 に、ファイルのアップロードを処理するスクリプトを示します。このスクリプトは以下のステップを実行します。

  1. ブラウザーの種類に応じてアップロード・ウィンドウのタイトルを判断します。
  2. アップロード・ウィンドウをアクティブにします。
  3. 編集ボックスにファイルのパスを挿入します。
  4. ファイルを送信します。
リスト 14. アップロードを処理するための AutoIt スクリプト
;first make sure the number of arguments passed into the scripts is more than 1 
If $CmdLine[0]<2 Then Exit EndIf
 handleUpload($CmdLine[1],$CmdLine[2])

;define a function to handle upload
 Func handleupload($browser, $uploadfile)
	 Dim $title                          ;declare a variable
            ;specify the upload window title according to the browser
            If $browser="IE" Then                  ; stands for IE;
 	      $title="Select file"
            Else                                 ; stands for Firefox
	       $title="File upload"
            EndIf
 
            if WinWait($title,"",4) Then ;wait for window with 
title attribute for 4 seconds;
                   WinActivate($title)                  ;active the window;
                   ControlSetText($title,"","Edit1",$uploadfile)   ;put the 
file path into the textfield  
                   ControlClick($title,"","Button2")                ;click the OK 
or Save button
            Else
	        Return False
            EndIf
 EndFunc 

Java コードの中で、AutoIt が作成した .exe ファイルを実行する関数を定義し、「Browse (参照)」ボタンがクリックされた後でその関数を呼び出します。

リスト 15. AutoIt が作成した .exe ファイルを実行する
public void handleUpload(String browser, String filepath) {
	String execute_file = "D:\\scripts\\upload.exe";
	String cmd = "\"" + execute_file + "\"" + " " + "\"" + browser + "\""
				+ " " + "\"" + filepath + "\""; //with arguments
	try {
		Process p = Runtime.getRuntime().exec(cmd);
		p.waitFor(); //wait for the upload.exe to complete
	} catch (Exception e) {
		e.printStackTrace();
	}
}

リスト 16 は Internet Explorer のダウンロード・ウィンドウを処理するための AutoIt スクリプトです。ダウンロード・スクリプトは Internet Explorer と Firefox とで異なります。

リスト 16. Internet Explorer におけるダウンロードを処理するための AutoIt スクリプト
If $CmdLine[0]<1 Then Exit EndIf
handleDownload($CmdLine[1])
Func handleDownload($SaveAsFileName)
Dim $download_title="File Download" 
If WinWait($download_title,"",4) Then
    WinActivate($download_title)
    Sleep (1000)
    ControlClick($download_title,"","Button2","")
    Dim $save_title="Save As"
    WinWaitActive($save_title,"",4)
    ControlSetText($save_title,"","Edit1", $saveAsFileName)
    Sleep(1000)
    if FileExists ($SaveAsFileName) Then
	FileDelete($SaveAsFileName)
	EndIf
    ControlClick($save_title, "","Button2","")
    Return TestFileExists($SaveAsFileName)
Else
    Return False
EndIf
EndFunc

AutoIt スクリプトの作成は容易ですが、ブラウザーの種類やバージョンによってウィンドウのタイトルやウィンドウのコントロール・クラスが異なるため、AutoIt スクリプトはブラウザーの種類やバージョンに依存します。


警告ダイアログ、確認ダイアログ、入力ダイアログの情報を検証する方法

window.alert() によって生成された警告ダイアログの場合には、その前のアクションの間に JavaScript で生成された警告ダイアログのメッセージを selenium.getAlert() を使用して取得します。何も警告がない場合、この関数は失敗します。警告を取得すると、手動で「OK」をクリックしたのと同じ効果を得ることができます。

window.confirmation() によって生成された確認ダイアログの場合には、その前のアクションの間に JavaScript で生成された確認ダイアログのメッセージを selenium.getConfirmation() を使用して取得します。この関数はデフォルトで真を返すため、手動で「OK」をクリックしたのと同じ効果を得ることができます。この動作を変更するには、この関数を実行する前に chooseCancelOnNextConfirmation コマンドを実行します。

window.prompt() によって生成された入力ダイアログの場合には、その前のアクションの間に JavaScript で生成された、質問への入力を促すダイアログのメッセージを selenium.getPromt() を使用して取得します。入力を適切に処理するためには、この関数を実行する前に answerOnNextPrompt コマンドを実行します。

Selenium を使用する場合、JavaScript による警告は目に見える警告ダイアログとしてポップアップ表示されるわけではありませんが、これらのポップアップ・ダイアログを処理しないと、想定外の警告があるという内容の例外が発生し、その結果としてテスト・ケースが失敗してしまいます。

参考文献

学ぶために

製品や技術を入手するために

  • Selenium をダウンロードしてください。
  • TestNG を入手してください。TestNG は柔軟なテスト・フレームワークであり、Selenium を使用したテストにも使用することができます。
  • AutoIt 3 をダウンロードしてください。AutoIt 3 は BASIC に似たフリーウェアのスクリプト言語であり、Windows GUI や一般的なスクリプトを自動化するために設計されています。
  • 皆さんの次のオープンソース開発プロジェクトを IBM ソフトウェアの試用版を使って革新してください。ダウンロード、あるいは DVD で入手することができます。
  • IBM 製品の評価版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2、Lotus、Rational、Tivoli、WebSphere などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source
ArticleID=782576
ArticleTitle=Selenium を使用して Web テストを自動化する
publish-date=01062012