ブログBlog

    • Selenium WebDriverで実践的テストケースを作成する(node.js編)

    • 2016年3月30日
    • Node.js
    • Selenium WebDriver
前回→Selenium WebDriverで実践的テストケースを作成する(Java編) 皆さんこんにちは。 最近は家事もこなす在宅ワーカーとして活動している中野です。 前回に引き続き、今回もseleniumを取り上げます。 「Selenium WebDriver」は複数のスクリプトで実行が可能ですが、 今回はnode.jsを使ってみます。

環境設定

(1)node.jsのインストール https://nodejs.org/en/download/ ローカルのマシンにあわせて、適切なインストーラをダウンロードして下さい。 ターミナルで $ node -v と入力して、バージョンが表示されれば成功です。 (2)selenium webdriverのインストール $ npm -g install selenium-webdriver (macの場合、事前にxcodeをインストールしておく必要があります。)

挙動確認

firefoxであれば、以上の設定で動かすことができます。 最もシンプルなスクリプトで挙動を確認してみましょう。
//firefoxTest.js
var webdriver = require('selenium-webdriver');
var driver;

driver = new webdriver.Builder()
.forBrowser('firefox')
.build();

driver.get('https://www.google.co.jp/').then(function(){
  driver.quit();
});
driver.get(‘https://www.google.co.jp/’)の結果、Promiseが返却されるので then(callback)で受け取ることができます。 この例では、単純にdriverを終了させています。 $ node firefoxTest.js とコマンドを実行して、firefoxが起動すれば成功です。 chromeで動かす場合は、javaの時同様、chromedriverという実行ファイルが必要になります。 zipを解凍して入手した実行ファイルを、jsファイルと同じフォルダに置いて下さい。
//chromeTest.js
var webdriver = require('selenium-webdriver');
var driver;

driver = new webdriver.Builder()
.withCapabilities(webdriver.Capabilities.chrome())
.build();

driver.get('https://www.google.co.jp/').then(function(){
  driver.quit();
});
webdriverをbuildする際に、withCapabilitiesというオプションで chromeを指定します。 $ node chromeTest.js とコマンドを実行すれば、chromeが起動します。

テスト準備

テスト対象とするWebアプリは前回と同じサンプルを使います。 selenium登録画面

テストスクリプト実装

テストフレームワークの準備

テストスクリプトを実装するにあたり、 mochaというJavaScriptのテスティングフレームワークを使用します。 また、mochaにはアサーションの機能がないため、アサーションライブラリとしてexpect.jsを使います。 ワークディレクトリに移動し、以下のコマンドでインストールします。 $ npm install mocha $ npm install expect.js 枠組みとしては以下のソースを用意しました。
//chromedriverTest.js
var webdriver = require('selenium-webdriver');
var t = require('selenium-webdriver/testing');
var expect = require('expect.js');
var driver;
var assert = require('assert');
var By = webdriver.By;

t.describe('account test', function() {
    var read = false;//ブラウザ起動が完了したかどうか

    //全テストの実行前に行う処理
    t.before(function() {
      driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

      driver.get('http://192.168.33.10').then(function(){
        read = true;
      });
    });

    //全テスト完了後に行う処理
    t.after(function() {
      driver.quit();
    });

    //実行したいテストパターン
    t.it('web app test1', function() {
      driver.wait(new webdriver.until.Condition('start up browser', function(){return read;}), 10000)
      .then(function(){
        //テスト処理
      });
    });

    //実行したいテストパターン
    t.it('web app test2', function() {
      //テスト処理
    });

});
beforeには全てのテスト実行前に行う処理、afterには全てのテスト完了後に行う処理を記述します。 具体的なテストはitのところに記述します。 また、ブラウザ起動のため、waitをかけている箇所がありますが、これについては後述します。 実行は以下のコマンドで行えます。 $ mocha chromedriverTest.js --timeout 10000 「–timeout」の箇所はmochaのオプションで、指定した時間内にテストが終わらない場合、エラーになります。 mocha実行結果 実行すると、上記の様にターミナルに表示されます。 ダメなテストケースがある場合は、failingと赤字で表示されるのですぐにわかります。

テストの実装

前回同様、お名前についてテストを実装してみます。 ロジックは既にわかっているので、同様のステップで処理を記述します。
    //(1)未入力の状態で登録ボタンをクリックして、エラーメッセージが表示されるか
    t.it('web app name test1', function() {
      driver.wait(new webdriver.until.Condition('start up browser', function(){return read;}), 10000)
      .then(function(){
				//(1-1)登録ボタンの要素を取得しクリック
				driver.findElement(By.id('register_button')).click()
				.then(function(){
					//(1-2)お名前のエラーメッセージ要素を取得しテキストを取得
					driver.findElement(By.id('user_name_error')).getText()
					.then(function(text){
						//(1-3)エラーメッセージが「お名前は入力必須です」であること
						expect(text).to.be('お名前は入力必須です');
					});
				});
      });
    });

    //(2)名前を入力するとエラーメッセージが表示されなくなること
    t.it('web app name test2', function() {
      //(2-1)お名前の要素を取得し、「名前」と入力
      driver.findElement(By.id('user_name')).sendKeys('名前')
      .then(function(){
        //(2-2)登録ボタンの要素を取得しクリック
        driver.findElement(By.id('register_button')).click()
        .then(function() {
          //(2-3)お名前のエラーメッセージ要素を取得しテキストを取得
          driver.findElement(By.id('user_name_error')).getText()
          .then(function(text){
            //(2-4)エラーメッセージが空白であること
            expect(text).to.be('');
          });
        });
      });
    });
driverの処理結果がPromiseで返ってくるため、thenで繋いで書いていくのが Javaと異なる点です。他のテスト項目も同様に展開すれば完成です。

より実践的に使いこなす

・JavaScriptの直接実行 executeScript  driverの提供している機能を使うことでコンポーネントの基本的な操作はできますが、 ブラウザのスクロールバーを動かしたい場合などは、標準の機能では実現することができません。 ですが、driver経由でネイティブなJavaScriptを実行することができます。
driver.executeScript("window.scrollTo(0, 3000)")
.then(function(){
 ... 
}); 
といったようにexecuteScript内にJavaScriptを記述することができます。 これにより、画面操作における制約はほぼ無くなったのではと思います。    ※ Javaの場合、driver.ExecuteJavaScript(“xxxxx”)で同様のことが実現できます。 ・待つことが必要な場合 wait 前回同様にcontroller.jsの読み込み時間を0から5000に変更して、再度スクリプトを実行してください。 そうすると、 ElementNotVisibleError: element not visible (Session info: chrome=49.0.2623.87) (Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Mac OS X 10.10.5 x86_64) といったエラーが表示されます。 これは、画面にコンポーネントが表示される前にスクリプトが実行されてしまったためです。 これを解消するため、以下を追記して下さい。
driver.wait(webdriver.until.elementIsVisible(
 driver.findElement(By.id('register_button'))), 8000)
.then(function(){
 ... 
});
driver.waitは1つ目の引数で指定された関数がtrueになるまで、2つ目の引数で指定されたミリ秒waitします。 timeoutになった場合は、エラーになります。 この一文を加えることで、指定したelementが表示されるまでwaitしてくれるので、先ほど発生したエラーが起きることなくテストが実行できるようになります。 また、画面の読み込みの際に、DOM上にelementが存在しない状態で、findElementを行ってしまうと、エラーになります。 そういった場合には
driver.wait(webdriver.until.elementLocated(
 By.id('register_button')), 8000)
.then(function(){
 ... 
});      
でelementが配置されるまで、waitをかけることで、エラーを回避することができます。 「Selenium WebDriver」を使ってjavaとnode.jsの両方でテストスクリプトを書いてみた結果、 ほぼ同等のクオリティだと感じました。それだけ「Selenium WebDriver」の完成度が高いということだと思います。 テストスクリプトとして採用する場合、javaには安定感がありますが、現時点だとnode.jsがオススメですね。 今回は以上になります。

この記事を書いた人 : 中野健一

一覧へ戻る

開発についてのお問い合わせはこちら

お問い合わせ

JOIN OUR TEAM

積極採用しています。私たちと一緒に働きませんか?