Selenium
勉強会

【社内勉強会】Seleniumの紹介(2017/08/09)

はじめに


注意事項

  • 私は、Seleniumを使ってテストコードは書いていません。

前提知識

  • HTMLの基礎
  • CSSセレクタ

参考図書

Selenium実践入門.jpg

『Selenium実践入門』技術評論社


目次

  1. Seleniumの概要
  2. Sleniumを動かしてみる
  3. Seleniumでできること
  4. Selenium IDE

1. Seleniumの概要


Seleniumとは

  • Webアプリケーションの画面操作を自動化するツール。
  • 主に画面テストの自動化に使われる
  • テスト以外にも使われる
    • 大量のデータの登録などの単純作業
    • Webスクレイピング

Selenium automates browsers. That's it!

http://www.seleniumhq.org/ 引用


Seleniumを構成する主なツール

Seleniumはツールの集合体。単体のツールではない。

  • Selenium WebDriver(以下、WebDriver)

    • Java, Ruby, JavaScriptなどのプログラミング言語から、ブラウザ操作が可能
    • 本格的なテスト自動化に適している (コードの共通化などによるメンテナンスコスト削減が可能なので)
  • Selenium IDE

    • ブラウザ操作を記録して再生できるFirefoxのアドオン
    • Seleniumの体験に適している
    • 本格的な運用には適していない

Selenium Project 引用


Seleniumがサポートしている主なプラットフォーム

  • ブラウザ
    • Firefox
    • Chrome
    • Internet Explore
    • Microsoft Edge
    • PhantomJS(後述)
  • OS
    • WIndows
    • Mac OS X
    • Linux
  • プログラミング言語
    • Java
    • C#
    • Python
    • JavaScript
    • Python
    • Ruby

Platforms Supported by Selenium 参考


2. Seleniumを動かしてみる


テスト対象のサイト

<input type="text" id="inputX"><input type="text" id="inputY"><input type="text" id="result" readonly>
<br>
<button type="button" id="calculate" onclick="calculate();">Calculate</button>
function calculate() {
  var result = Number(document.getElementById("inputX").value) + Number(document.getElementById("inputY").value);
  document.getElementById("result").value = result;
}

実行環境の構築

  • Selenium 3.4.0
  • JUnit 4.12
  • Firefox 54.0
  • geckodriver v0.18.0
    • Firefox用のドライバ
    • exeファイルを適当のフォルダに配置
pom.xml
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.4.0</version>
    </dependency>
</dependencies>

Seleniumを使ったテストコード

SampleTest.java
public class SampleTest {
    WebDriver driver;

    @Before
    public void setUp() throws Exception{
        //geckodriver.exeのパスを設定
        System.setProperty("webdriver.gecko.driver", "/tmp/geckodriver.exe");
        //Firefox起動
        driver  = new FirefoxDriver();
        //画面遷移
        driver.get("file:///C:/tmp/sample.html");
    }

    @Test
    public void 入力値が12のときの加算結果が表示される() {
        //テキストボックスに"1"を入力する
        WebElement xElm = driver.findElement(By.id("inputX"));
        xElm.clear();
        xElm.sendKeys("1");
        //テキストボックスに"2"を入力する
        WebElement yElm = driver.findElement(By.id("inputY"));
        yElm.clear();
        yElm.sendKeys("2");
        //ボタンを押す
        driver.findElement(By.id("calculate")).click();

        //計算結果用のテキストボックスのvalue属性値を取得
        String actual = driver.findElement(By.id("result")).getAttribute("value");
        String expected = "3";
        //期待結果の比較
        assertThat(actual, is(expected));
    }

    @After
    public void tearDown() throws Exception{
        driver.quit();
    }
}

3. Seleniumでできること


Selenium WebDriverの仕組み

selenium 仕組み.png
https://app.codegrid.net/entry/selenium-1 引用


WebDriverでできること part1

  • 要素の取得
    • ID属性の値
    • CSSセレクタ記法
    • XPath記法
  • 要素の操作
    • URL遷移
    • クリック
    • キー入力
    • チェックボックス、ラジオボタン、プルダウンの選択
    • subnit
  • 要素情報の取得
    • 表示・非表示
    • 有効・無効
    • 存在するかどうか
    • 選択状態
    • 属性、テキスト、タグ名
    • CSSプロパティ
    • サイズ、位置
  • ブラウザ情報の取得
    • タイトル、URL
    • HTMLソース
    • ウィンドウ位置、ウィンドウサイズ
    • Cookie

※ 『Selenium 実践入門』4.3~4.6章 参考
Selenium Web Driver 参考


WebDriverでできること part2

  • 画面キャプチャ
  • JavaScriptの実行
  • ブラウザの戻る、進む
  • 待ち処理
  • Alert, Cnfirm, Promptダイアログの操作
    • Safari, PahntomJsのドライバでは操作できないらしい(未確認)
    • ダイアログが表示された状態の画面キャプチャは取得できない
  • ウィンドウの操作
  • フレームの操作
  • マウス・キーボード操作
    • ダブルクリック、右クリック
    • マウスの移動、ドラッグ&ドロップ
    • キーを押しながらクリック

※ 『Selenium 実践入門』4.7~4.10章 参考


WebDriverでできないけど、工夫すればなんとかできること

  • ファイルアップロードダイアログ

    • ダイアログを直接操作できない
    • 対応案: input要素にsendKeyメソッドで直接パスを入力する
  • ファイルダウンロード

    • ダイアログを直接操作できない
    • 対応案1:ブラウザ設定で、ダウンロードダイアログを非表示にする
    • 対応案2:ブラウザ設定で、ダウンロードディレクトリを指定する
    • InternetExploreDirverでは確認ダイアログを非表示にできない(未確認)
  • 新しいtypeのinput要素(HTML5から導入)

    • typeが日付・時刻
    • typeがrange
    • typeがcolor
    • 対応案:JavaScriptでvalue属性の値を設定する

※ 『Selenium 実践入門』5章 参考


[私見] WebDriverのできる/できないの勘所

  • JavaScriptができることは、WebDriverもできる
  • ブラウザごとに動きやレイアウトが異なる機能は、できない場合がある
    • ダイアログなど
  • セキュリティの観点で制限がある機能は、できない場合がある
    • ファイル操作

4. Selenium IDE


[Try] Selenium IDEの操作

  • 記録の開始
  • テストの再生
    • 速度調整
  • テストケースの保存
    • HTMLファイル
  • プログラミング言語へのエクスポート

Selenium IDEの特徴

  • ブラウザ操作を記録して再生できるFirefoxのアドオン
  • テストコードがHTMLファイルのため自由度が低い
    • if文やfor文が書きにくい(書くことは可能)
  • 古いSeleniumがベースになっているので、WebDriverよりできることが少ない

[補足] Selenium Builder


Selenium IDEの要素取得(locator)

  • locatorの優先度(ID, css, xpathなど)は、設定で変更できる
  • ID属性がない要素のlocatorは読みにくい
  • たとえば、以下のボタン操作を記録した場合、2個目のボタンはXPATHを使ったlocatorになる
<!-- locaitor: css="button.sample" -->
<button class="sample" >sample</button>
<!-- locator: css="button.sample" -->
<button class="sample" >sample</button>

[私見] Selenium IDEでテスト自動化を行うべきか?

  • Selenium IDEのコード(HTMLファイル)で自動化するのは、非現実的
    • 共通化が難しい
    • クロスブラウザテストが難しい(できなくはなない)
  • Selenium IDEのコードからエクスポートしたWebDriverのコードで、テスト自動化した方がよさそう。上記の問題は解決できる。

  • 間違った操作も記録されるが、それを修正するのが面倒。

  • WebDriverに慣れたら、Selenium IDEで記録するより、直接WebDriverでコードを書いた方が、生産性が良さそう


付録


ページオブジェクトパターン

  • メンテナンス性の高いコードを作成する共通化技法
  • テスト対象の画面情報を共通クラスに集約
    • 画面構成の修正に伴う修正コストを削減

ページオブジェクトパターンのサンプル

  • 以下のソースはページオブジェクトパターンで書いたコード。たとえば、ボタンのID属性値"calculate"が変わっても、テストコードは1か所を変えるだけでよい。
CalculatePage.java
public class CalculatePage {
    private WebDriver driver;

    public CalculatePage(WebDriver driver) {
        this.driver = driver;
    }

    /** 計算ボタン */
    @FindBy(id = "calculate")
    private WebElement calculateButton;

    /** 計算ボタンを押す */
    public void calculate() {
        calculateButton.click();
    }
}

Selenium関連のライブラリ

WebDriverのコマンドは冗長

  • Geb

    • Groovy言語(Java言語の拡張)で簡潔に記述できる
    • jQuery記法に近い記述で、要素を取得できる
  • Fluentlenium

    • Javaで簡潔に記述できる
    • jQuery記法に近い記述で、要素を取得できる
    • Page Object Patternを支援する機能を持つ

私はFluentleniumを使っている。

FleuentleniumSample.java
//WebDriverの記述
driver.findElement(By.id("calculate")).click();
//Fluentleniumの記述
$("calculated").click();

PhantomJS

  • ヘッダレスブラウザ
  • UIを持たないブラウザ
  • 高速に動作する

WebDriverはテスト用の機能がない

期待結果の検証はJunitを使っているが、JUnitでなくてもよい。


テスト自動化の参考サイト


Selenium以外のWebテストツール

他のツールと比較したSeleniumの特徴


その他の感想

  • IE実行の環境設定が面倒。そしてハマりやすい。

Seleniumを使う際の工夫

  • 要素の取得や結果の比較には、できるだけ変更されにくい値(IDやname属性値など)をを、参照すること

  • 「JavaScriptのエラーがないこと」を確認するのは簡単なので、テストコードに組み込んだ方がよさそう