Selenium プロジェクトのツール・スイートに含まれている Selenium Remote Control (RC) は、Web アプリケーションのテストを自動化するためのフレームワークです。Selenium RC は多くのプログラミング言語をサポートし、またほとんどすべてのブラウザーに対応しています。Selenium RC の最も重要なメリットはブラウザーの駆動方法にあります。Selenium RC は他の Web UI 自動化ツールとは異なり、JavaScript によってブラウザーを駆動するため、マウス・イベントによってテストが妨害されることがありません。そのため、テスターはテストが実行されている間も他の作業を行うことができます。
Selenium RC を拡張して複数のサーバーで並列にテストを実行できるようにした Selenium Grid は、さまざまなオペレーティング・システムの各種ブラウザーでテストを行うのに要する時間を削減することができ、ひいてはコストを削減することができます。
Selenium ツール・スイートは、正式なドキュメントやガイダンスが限られたオープンソースのプロジェクトであるため、学習するのに時間がかかる可能性があります。この記事では、Selenium Grid (バージョン 1.0.6) を使用してテストを作成し、Java でプログラミングを行い、TestNG テスト・フレームワークを使用してテストを実行する方法について学びます。
Selenium Grid には Selenium Hub と Remote Control という 2 つのコンポーネントがあります。Selenium Hub は (Selenium RC と同様に) テストからリクエストを受信し、Selenium Hub に登録されている Remote Control を各テストに割り当てます (図 1)。
図 1. Selenium Grid の Selenium Hub と Selenium RC の関係
Selenium Grid では、テスターはコードを変更することなくテストを実行することができます。すべてのプロセスは自動的に実行され、テスターは実際のインフラストラクチャーを知る必要も気にする必要もありません。
Selenium RC を理解している人であれば、Selenium Grid を使用して容易にテストを実行できるはずです。また既存のコードを複数のマシンで並列に実行することもできるため、テストの実行時間を短くすることができ、テスト結果を短時間で得ることができます。ただし Selenium Grid 自体には並列実行機能はありません。Selenium Grid を活用するためには、Selenium テストを並列モードで作成する必要があります。
Selenium Grid を使用するためには、まず Selenium Grid をダウンロードしてインストールする必要があります (「参考文献」のリンクを参照)。Selenium Grid はライブラリーの JAR ファイルやサンプル・ファイル、Ant のビルド・ファイルなどを含むフォルダーです。Selenium Grid でテストを実行するためには以下のものが必要です。
- Ant バージョン 1.7 またはそれ以降: Java アプリケーション (ビルド・ファイルの中でターゲットと拡張ポイントとして記述されます) のコンパイル、アセンブル、テスト、実行に使用します。
- JDK 5 またはそれ以降。
- Selenium RC の基礎知識: これは Selenium Grid が Selenium RC をベースにしているためです。(Selenium RC については「参考文献」を参照)。テスターは Selenium RC を使用したテストの作成方法と実行方法を理解している必要があります。
この記事で紹介する例では、Java 技術と TestNG をプログラミング言語およびテスト・フレームワークとして使用します。TestNG は多種多様なテスト要求を単純化し、JUnit を拡張できるように設計されています (TestNG の詳細については「参考文献」を参照)。TestNG の構成ファイルの簡単な例をリスト 1 に示します。
リスト 1. 簡単な TestNG 構成ファイル
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite1" parallel="methods" thread-count="2">
<test name="Testcase20" >
<classes>
<class name="com.test.workflow.device.testcase20"/>
</classes>
</test>
</suite>
|
<suite> タグは、1 つ以上のテストが含まれる TestNG XML
ファイルを表すことができます。<test> タグは 1 つ以上の TestNG クラスを含む 1
つのテストを指定することができ、<class> タグは 1 つ以上のテスト・メソッドを含む 1 つの
TestNG クラスを指定することができます (タグの詳細については「参考文献」を参照)。テスト・メソッドは Java ファイルで定義されます (リスト 2)。
リスト 2. Java ファイルで定義されたテスト・メソッド
@Test
public void testMethod()
{
....
}
|
テスターは Java プログラミング言語とテスト・フレームワークを使用してテスト・スクリプトを作成し、Ant を使用してコマンドラインから TestNG クラスを実行します。では Ant を使用して TestNG を実行するためのプロセス全体を見てみましょう
- コマンドラインで
ant(ターゲット名) [ビルド・ファイル名]を実行します。 - Ant が build.xml ファイルを読み取り、プロジェクトのパラメーター、インポート・ファイル、クラスパス定義、ターゲットの定義、等々を取得します。
- Ant が Java ソース・コードをコンパイルして TestNG クラスにします。
- Ant は実行対象のターゲットに注目し、ターゲットの構成を取得します。
- TestNG 構成ファイルを読み取り、パラメーター、テスト・クラスの名前、等々を取得します。
- TestNG 構成ファイルの構成に従って TestNG クラスを実行します。
この記事では、TestNG と Ant を統合した Selenium Grid を使用して並列にテストを実行する方法に焦点を絞ります。そこで、PHP ページをベースとする単純なアプリケーションを使用します。このテスト・ケースは単純にページ上のタブをクリックするように設計されています。図 2 はアプリケーションの Web ページのサンプルを示しています。
図 2. アプリケーションの Web ページの一部
リスト 3 はタブのサンプル・ソース・コードを示しています。
リスト 3. タブのソース・コード
<div class="Tabs" style="width: 100%;"> <a class="Current">Test Case</a> <a>View Time</a> <a>Run Scripts</a> <a>Long Run</a> <a>LA</a> <a>s-CAT</a> <a>Jmeter</a> </div> |
テスト・マシンを以下のように準備します。
| IP | OS の種類 |
|---|---|
| 9.181.138.75 | win2003 |
| 9.181.138.186 | win2003 |
| 9.181.128.184 | Linux |
図 3 に示す内容を持つテスト・フォルダーを selenium-grid-1.0.6 ディレクトリーに配置します。
図 3. テスト・ケースのフォルダーの内容
src ディレクトリーには Java ソース・コードのファイルが含まれています。target ディレクトリーにはコンパイルされたすべてのクラス・ファイルとレポート・ファイルがすべて含まれています。リスト 4 の build.xml ファイルはターゲットの構成を定義する Ant ビルド・ファイルです。このファイルには、どの TestNG 構成ファイルを呼び出すのか、プロジェクトのパラメーター、ライブラリー・ファイルのパス、等々が含まれています。testng.xml ファイルはサンプル・テスト・ケースの TestNG 構成ファイルです。
リスト 4. build.xml
<project name="Selenium Grid Test" default="run" basedir=".">
<description>Selenium Grid Test</description>
<property name="rootdir" value="${basedir}/.."/>
<property file="${rootdir}/project.properties"/>
<property name="name" value="Selenium Grid Demo"/>
<property name="artifact" value="selenium-grid-demo"/>
<property name="version" value="SNAPSHOT"/>
<property name="selenium.version" value="SET ME"/>
<property name="build.src" location="src"/>
<import file="${rootdir}/lib/build/common-build.xml" />
<path id="compile.classpath">
<fileset dir="${rootdir}/vendor">
<include name="selenium-java-client-driver-${selenium.version}.jar"/>
<include name="testng-5.7-jdk15.jar"/>
<include name="commons-logging-1.0.4.jar"/>
</fileset>
<pathelement location="${rootdir}/tools/target/classes"/>
<pathelement location=
"${rootdir}/tools/target/dist/lib/selenium-grid-tools-standalone-${version}.jar"/>
<pathelement location="${rootdir}/lib/selenium-grid-tools-standalone-${version}.jar"/>
<pathelement path="${java.class.path}/"/>
</path>
<path id="runtime.classpath">
<path refid="compile.classpath"/>
<pathelement path="${build.output}/"/>
</path>
<target name="run" depends="compile" description="test">
<java classpathref="runtime.classpath"
classname="org.testng.TestNG"
failonerror="true">
<sysproperty key="java.security.policy" file="${rootdir}/lib/testng.policy"/>
<arg value="-d" />
<arg value="${basedir}/target/reports" />
<arg value="-suitename" />
<arg value="suite1" />
<arg value="testng.xml"/>
</java>
</target>
<target name="build" depends="compile"/>
<target name="dist" depends="build"/>
<target name="coverage-analysis" />
</project>
|
これで環境とテスト・データの準備ができたので、以下の 3 つの異なるシナリオで並列テストを実行することができます。
- 1 台のサーバー上の別々のブラウザーで同じテスト・ケースを実行する
- 別々のサーバーの別々のブラウザーで別々のテスト・ケースを並列に実行する
- 別々のサーバーの同じブラウザーで別々のテスト・ケースを並列に実行する
1 台のサーバー上の別々のブラウザーで同じテスト・ケースを実行する
1 台のサーバー上の別々のブラウザーで同じテスト・ケースを実行するには、以下のようにして Selenium Grid のディストリビューション・ディレクトリーにアクセスします。
ant launch-hub |
同じマシン、または別のマシンの新しいウィンドウで、以下の内容を入力するか、
ant launch-remote-control ant Denvironment=*iehta launch-remote-control |
あるいは以下の内容を入力します。
ant -Dhost=9.181.138.186 DhubURL=http://9.181.138.75:4444 launch-remote-control
ant -Dhost=9.181.138.186 DhubURL=http://9.181.138.75:4444
-Denvironment=*iehta launch-remote-control
|
ブラウザーで http://localhost:4444/console にアクセスし、Selenium Grid Hub のコンソールに戻ります。すると、利用可能なリモート・コントロールが図 4 のように 2 つ表示されるはずです。
図 4. Selenium Grid Hub のコンソール
テスト・クラスのソース・コード (リスト 5) を src ディレクトリーに配置します。
リスト 5. テスト・ケースの Java ソース・コード
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import org.testng.annotations.Parameters;
public class GridTest2 {
String url = "http://9.181.138.186/index.php";
private Selenium selenium= null;
@Parameters({ "bs" })
@BeforeClass
public void startBroswer(String broswer)
{
selenium= new DefaultSelenium("localhost", 4444, broswer, url);
selenium.start();
selenium.open(url);
selenium.windowMaximize();
}
@Test
public void test() throws InterruptedException
{
selenium.click("xpath=//a[contains(text(),\'LA\')]");
Thread.sleep(10000);
}
@AfterClass
public void clear() {
selenium.stop();
}
}
|
testng.xml の内容をリスト 6 のように変更します。
リスト 6. TestNG 構成ファイルの内容
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="suite1" verbose="1" annotations="JDK" parallel="tests" thread-count="2">
<test name="test1">
<parameter name="bs" value="*firefox"/>
<classes>
<class name="GridTest2" />
</classes>
</test>
<test name="test2">
<parameter name="bs" value="*iehta"/>
<classes>
<class name="GridTest2" />
</classes>
</test>
</suite>
|
testng.xml ファイルでは、bs パラメーターによって、test1 を Firefox で実行し、test2 を
Internet Explorer で実行することが指定されています。また <suite> タブの parallel 属性によってテストを並列に実行することが、thread-count 属性によって実行するスレッドの数が指定されています。ここでは 2 つのテストのみが定義されているため、2 つのテストが同時に実行されます。
ウィンドウを開き、テスト・ディレクトリーにアクセスし、以下のコマンドを実行します。
ant run |
これにより、テスト・ケースが自動的に実行されます。
別々のサーバーの別々のブラウザーで別々のテスト・ケースを並列に実行する
別々のサーバーの別々のブラウザーで別々のテスト・ケースを並列に実行するためには、以下のコマンドを実行することで Selenium Grid のディストリビューション・ディレクトリーにアクセスします。
ant launch-hub |
同じマシンの新しいウィンドウで、または別のマシンのウィンドウで、以下のコマンドを入力します。
ant launch-remote-control ant Dport=6666 Denvironment=*iehta launch-remote-control |
9.181.138.186 のマシンのウィンドウに以下のコマンドを入力します。
ant -Dhost=9.181.138.186 DhubURL=http://9.181.138.75:4444 launch-remote-control |
9.181.138.184 のマシンのウィンドウに以下のコマンドを入力します。
ant -Dhost=9.181.138.184 DhubURL=http://9.181.138.75:4444 launch-remote-control |
ブラウザーで http://localhost:4444/console にアクセスし、Selenium Grid Hub のコンソールに戻ります。すると、利用可能なリモート・コントロールが図 5 のように 4 つ表示されるはずです。
図 5. Selenium Grid Hub のコンソール
テスト・クラスのソース・コード (リスト 7) を src ディレクトリーに配置します。
リスト 7. テスト・ケースの Java ソース・コード
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
public class GridTest2(3/4) {
String url = "http://9.181.138.186/index.php";
private Selenium selenium= null;
@Parameters({ "bs" })
@BeforeClass
public void startBroswer()
{
selenium= new DefaultSelenium("localhost", 4444, broswer, url);
selenium.start();
selenium.open(url);
selenium.windowMaximize();
}
@Test
public void test() throws InterruptedException
{
selenium.click("xpath=//a[contains(text(),\'View Time\')]");
//any code is ok
Thread.sleep(10000);
}
@AfterClass
public void clear() {
selenium.stop();
}
}
|
testng.xml ファイルの内容をリスト 8 のように変更します。
リスト 8. TestNG の構成ファイルの内容
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="suite1" verbose="1" annotations="JDK" parallel="tests" thread-count="2" >
<test name="test2" junit="false" >
<parameter name="bs" value="*iehta"/>
<classes>
<class name="GridTest2" />
</classes>
</test>
<test name="test3" junit="false">
<parameter name="bs" value="*firefox"/>
<classes>
<class name="GridTest3" />
</classes>
</test>
<test name="test4" junit="false">
<parameter name="bs" value="*firefox"/>
<classes>
<class name="GridTest4" />
</classes>
</test>
</suite>
|
定義されているスレッドは 2 つのみなので、同時に実行されるテスト・ケースは 2 つのみです。リモート・コントロールは 4 つありますが、Selenium Grid Hub は RC1 を選択して GridTest2 を実行し、残りのリモート・コントロールのうちのいずれか 2 つが GridTest3 と GridTest4 を実行します。どの 2 つのテストが並列に実行されるかはランダムに決まります。図 6 は Selenium Grid Hub の実行状態を示しています。
図 6. Selenium Grid Hub のコンソール
これら 3 つのテストをすべて同時に実行したい場合には、単純に thread-count を 3 に変更します。
別々のサーバーの同じブラウザーで別々のテスト・ケースを並列に実行する
別々のサーバーの同じブラウザーで別々のテスト・ケースを並列に実行するためには、以下のようにして Selenium Grid のディストリビューション・ディレクトリーにアクセスします。
ant launch-hub |
9.181.138.186 のマシンでウィンドウを開き、以下のコマンドを入力します。
ant -Dhost=9.181.138.186 DhubURL=http://9.181.138.75:4444 launch-remote-control |
9.181.138.184 のマシンでウィンドウを開き、以下のコマンドを入力します。
ant -Dhost=9.181.138.184 DhubURL=http://9.181.138.75:4444 launch-remote-control |
ブラウザーで http://localhost:4444/console にアクセスし、Selenium Grid Hub のコンソールに戻ります。すると、利用可能なリモート・コントロールが 3 つまたは 4 つ表示されるはずです。テスト・クラスのソース・コード (リスト 9) を src ディレクトリーに配置します。
リスト 9. テスト・ケースの Java ソース・コード
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import static com.thoughtworks.selenium.grid.tools.
ThreadSafeSeleniumSessionStorage.closeSeleniumSession;
import static com.thoughtworks.selenium.grid.tools.
ThreadSafeSeleniumSessionStorage.session;
import static com.thoughtworks.selenium.grid.tools.
ThreadSafeSeleniumSessionStorage.startSeleniumSession;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
public class GridTest {
String url = "http://9.181.138.186/index.php";
private Selenium selenium;
@BeforeMethod(alwaysRun = true)
protected void startSession() {
startSeleniumSession("localhost", 4444, "*firefox", url);
selenium = session();
selenium.open("/");
selenium.windowMaximize();
}
@AfterMethod(alwaysRun = true)
protected void closeSession() {
closeSeleniumSession();
}
@Test
public void test() throws InterruptedException
{
selenium.click("xpath=//a[contains(text(),\'View Time\')]");
Thread.sleep(10000);
}
@Test
public void test2() throws InterruptedException
{
selenium.click("xpath=//a[contains(text(),\'LA\')]");
Thread.sleep(10000);
}
@Test
public void test3() throws InterruptedException
{
selenium.click("xpath=//a[contains(text(),\'Test Case\')]");
Thread.sleep(10000);
}
}
|
testng.xml ファイルの内容をリスト 10 のように変更します。
このソース・コードは Selenium RC の一般的なスクリプトとは非常に異なっています。このコードでは Selenium オブジェクトをセッション・オブジェクトとして初期化しています。これは各メソッドを別々に実行する必要があるためです。そのため、Selenium はメソッドよりも前にセッションを開始し、メソッドよりも後にセッションを閉じる必要があります。
リスト 10. TestNG 構成ファイルの内容
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="suite1" verbose="1" parallel="methods" thread-count="2">
<test name="test" junit="false">
<classes>
<class name="GridTest" />
</classes>
</test>
</suite>
|
parallel 属性は methods に変更されています。これはクラスのメソッドが並列に実行されることを意味しています。クラスは順番に実行されます。
テスト結果を表示するのは非常に容易です。build.xml ファイルに定義されたターゲット・フォルダーにアクセスし、続いて reports フォルダーにアクセスします。index.html を開き、「suite name (スイート名)」リンクをクリックします。すると、図 7 のような結果が表示されるはずです。図 7 は 3 番目のサンプル・テストの結果です。
図 7. テスト結果
詳細を表示するためには、左側の「chronological (時系列)」リンクをクリックします。すると、図 8 のような詳細な情報が表示されます。
図 8. 詳細なテスト結果
この記事では Selenium Grid を使用して Selenium テストを並列に実行する方法について学びました。Selenium Grid を使用して Web アプリケーションのテストを自動化すると、大幅に時間を節約することができ、テスト人員も少なくて済みます。例えば 2 番目のシナリオで説明したように、1 人のテスターが 100 件のテスト・ケースを行う場合、10 個のスレッドを構成してテスト・ケースを実行すると、自動テストによって作業量と時間を 10 倍節約することができます。当然ですが、リモート・コントロールの数には制限があります。
また並列テストにより、リグレッション・テストもより重宝するようになります。この記事で学んだことを活用し、Web アプリケーションのテストを効率よく短時間で行えるようになることを願っています。
学ぶために
- SeleniumHQ のサイトを訪れ、多様なプラットフォームにわたって Web アプリケーションのテストを自動化する Selenium ツール・スイートのすべてを学んでください。
- Selenium と
Selenium RC のドキュメントを調べてください。このユーザー・ガイドには、Selenium の紹介、Selenium の機能の説明、そして Selenium コミュニティーによって蓄積された、よく使われるベスト・プラクティスが含まれています。
- Selenium Grid のサイトを訪れ、Selenium Grid によって複数マシンにテストを分散し、並列にテストを実行する方法を学んでください。
- TestNG について、そして TestNG Ant タスクの定義方法について学んでください。
- Apache Ant プロジェクトについての資料を読んでください。
- developerWorks の Technical events
and webcasts で最新情報を入手してください。
製品や技術を入手するために
- Selenium Grid をダウンロードしてください。
- Selenium
のテストにも使用できる柔軟なテスト・フレームワーク、TestNG を入手してください。
- Apache Ant を入手してください。Apache Ant は、相互に依存するターゲットと拡張ポイントとしてビルド・ファイルに記述されるプロセスを駆動するための Java ライブラリーであり、コマンドライン・ツールでもあります。
議論するために
- Selenium Grid コミュニティーに参加してください。
- 今すぐ developerWorks
のプロフィールを作成し、Selenium に関するウォッチ・リストを設定してください。developerWorks
コミュニティーとずっとつながっていられます。
- Web
開発に関心を持つ他の developerWorks メンバーを見つけてください。
- Web
の話題に焦点を絞った developerWorks のグループの 1 つに参加し、皆さんの知識を共有してください。
- Roland Barcia が彼のブログの中で Web
2.0 とミドルウェアについて語っています。
- developerWorks のメンバーが Web
のトピックに関して共有するブックマークを調べてみてください。
- 即座に答えを得るために、Web 2.0 Apps
フォーラムを訪れてください。
- 即座に答えを得るために、Ajax フォーラムを訪れてください。

