目次


Selenium Grid を使用して Web アプリケーションのテストを強化する

自動化された並列テストを複数の環境で実行する

Comments

はじめに

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 Grid には Selenium Hub と Remote Control という 2 つのコンポーネントがあります。Selenium Hub は (Selenium RC と同様に) テストからリクエストを受信し、Selenium Hub に登録されている Remote Control を各テストに割り当てます (図 1)。

図 1. Selenium Grid の Selenium Hub と Selenium RC の関係
この図では各コンポーネントを表すボックスが両方向の矢印で接続されています。テスト・スクリプトは Selenium Hub に接続され、Selenium Hub は別々の Selenium RC に接続されています。各 Selenium RC はそれぞれがブラウザーに接続され、各ブラウザーは Web アプリケーションに接続されています。
この図では各コンポーネントを表すボックスが両方向の矢印で接続されています。テスト・スクリプトは Selenium Hub に接続され、Selenium Hub は別々の Selenium RC に接続されています。各 Selenium RC はそれぞれがブラウザーに接続され、各ブラウザーは Web アプリケーションに接続されています。

Selenium Grid では、テスターはコードを変更することなくテストを実行することができます。すべてのプロセスは自動的に実行され、テスターは実際のインフラストラクチャーを知る必要も気にする必要もありません。

Selenium RC を理解している人であれば、Selenium Grid を使用して容易にテストを実行できるはずです。また既存のコードを複数のマシンで並列に実行することもできるため、テストの実行時間を短くすることができ、テスト結果を短時間で得ることができます。ただし Selenium Grid 自体には並列実行機能はありません。Selenium Grid を活用するためには、Selenium テストを並列モードで作成する必要があります。

Selenium Grid を使用する準備を整える

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 を実行するためのプロセス全体を見てみましょう

  1. コマンドラインで ant(ターゲット名) [ビルド・ファイル名] を実行します。
  2. Ant が build.xml ファイルを読み取り、プロジェクトのパラメーター、インポート・ファイル、クラスパス定義、ターゲットの定義、等々を取得します。
  3. Ant が Java ソース・コードをコンパイルして TestNG クラスにします。
  4. Ant は実行対象のターゲットに注目し、ターゲットの構成を取得します。
  5. TestNG 構成ファイルを読み取り、パラメーター、テスト・クラスの名前、等々を取得します。
  6. TestNG 構成ファイルの構成に従って TestNG クラスを実行します。

サンプル・テスト・ケース

この記事では、TestNG と Ant を統合した Selenium Grid を使用して並列にテストを実行する方法に焦点を絞ります。そこで、PHP ページをベースとする単純なアプリケーションを使用します。このテスト・ケースは単純にページ上のタブをクリックするように設計されています。図 2 はアプリケーションの Web ページのサンプルを示しています。

図 2. アプリケーションの Web ページの一部
アプリケーションの Web ページを示すスクリーン・ショット。この Web ページには次のタブが含まれています。Test Case (テスト・ケース)、View Time (時間を表示)、Run Scripts (スクリプトを実行)、Long Run (長時間実行)、LA、s-Cat、そして Jmeter です。
アプリケーションの Web ページを示すスクリーン・ショット。この Web ページには次のタブが含まれています。Test Case (テスト・ケース)、View Time (時間を表示)、Run Scripts (スクリプトを実行)、Long Run (長時間実行)、LA、s-Cat、そして Jmeter です。

リスト 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>

テスト・マシンを以下のように準備します。

IPOS の種類
9.181.138.75win2003
9.181.138.186win2003
9.181.128.184 Linux

図 3 に示す内容を持つテスト・フォルダーを selenium-grid-1.0.6 ディレクトリーに配置します。

図 3. テスト・ケースのフォルダーの内容
テスト・ケースのフォルダーの内容を示すスクリーン・ショット。このフォルダーには、src サブフォルダーと target サブフォルダー、そして build.xml ファイルと testing.xml ファイルが含まれています。

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 台のサーバー上の別々のブラウザーで同じテスト・ケースを実行するには、以下のようにして 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 のコンソール
Selenium Grid Hub のコンソールのスクリーン・ショット。利用可能なリモート・コントロールが 2 つ表示されています。
Selenium Grid Hub のコンソールのスクリーン・ショット。利用可能なリモート・コントロールが 2 つ表示されています。

テスト・クラスのソース・コード (リスト 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 のコンソール
Selenium Grid Hub のコンソールのスクリーン・ショット。利用可能なリモート・コントロールが 4 つ表示されています。
Selenium Grid Hub のコンソールのスクリーン・ショット。利用可能なリモート・コントロールが 4 つ表示されています。

テスト・クラスのソース・コード (リスト 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 のコンソール
Selenium Grid Hub のコンソールのスクリーン・ショット。利用可能なリモート・コントロールが 2 つ、アクティブなリモート・コントロールが 2 つ表示されています。
Selenium Grid Hub のコンソールのスクリーン・ショット。利用可能なリモート・コントロールが 2 つ、アクティブなリモート・コントロールが 2 つ表示されています。

これら 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. テスト結果
テスト結果のスクリーン・ショット。2 つのテーブルが表示されており、1 つのテーブルには、テストの合格/不合格/スキップの数、テスト開始日、合計時間、含まれるグループ、除外されたグループが表示されています。もう 1 つのテーブルには、テスト・メソッドと、合格したテストの実行時間 (秒) が表示されています。
テスト結果のスクリーン・ショット。2 つのテーブルが表示されており、1 つのテーブルには、テストの合格/不合格/スキップの数、テスト開始日、合計時間、含まれるグループ、除外されたグループが表示されています。もう 1 つのテーブルには、テスト・メソッドと、合格したテストの実行時間 (秒) が表示されています。

詳細を表示するためには、左側の「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 プロジェクトについての資料を読んでください。
  • Selenium Grid をダウンロードしてください。
  • Selenium のテストにも使用できる柔軟なテスト・フレームワーク、TestNG を入手してください。
  • Apache Ant を入手してください。Apache Ant は、相互に依存するターゲットと拡張ポイントとしてビルド・ファイルに記述されるプロセスを駆動するための Java ライブラリーであり、コマンドライン・ツールでもあります。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=696856
ArticleTitle=Selenium Grid を使用して Web アプリケーションのテストを強化する
publish-date=07082011