Selenium使ってみたら意外と簡単に始められた


Seleniumは前から「使ってみる」つもりでいましたが、「設定やら準備やら大変そう」と後回しにしてました。
最近、Seleniumを調べる機会があり「あれ?これすぐに始められるんじゃね?」って思い触ってみました。

要約

  • 作成したコードはGitHubに上げました。 ChromeDriverも含まれているので、Chromeのバージョンが合えばこのまま実行できるはず。
  • Selenium自体をテストフレームワークだと思っていたが、実際はブラウザーを制御するツールで、JUnitを使ってテストを書くことがわかった。
  • "BDDやATDDのテストケースを作る時"や"探索的テストの操作を再現したい時"に使うと便利。

前提

環境 条件
Selenium Selenium WebDriver(Selenium2)
実行マシン macOS High Sierra(10.13.5)
ブラウザ Google chrome(67.0.3396.87)
プログラム言語 Java
テストフレームワーク JUnit
ビルドツール maven

※Selenium-Serverは使わない。(ローカルPCを使ってChromeでテストするだけなので)

準備

Selenium Clientのダウンロード

Seleniumを実行するためのライブラリー

ChromeDriverのダウンロード

Seleniumからブラウザーを制御したり、ブラウザーの状態を取得するためのツール

ブラウザーごとに対応Driverがあり、今回はChromeで確認した

  • ダウンロードサイトサイトから使っているChromeのバージョンに合うDriverをダウンロードする。
  • (2018.6時点)Chromeは67だったので最新の2.40をダウンロードした
  • ダウンロードしたzipファイルを解凍して任意の場所に置く。(今回はMavenプロジェクト配下に置いた)

ChromeDriver wiki

Mavenプロジェクトの作成

  • pom.xmlのdependencyにselenium-javaを指定します
  • ダウンロードしたChromeDriverをコピーします

Seleniumを動かしてみた

公式サイトのSelenium WebDriverをベースにGoogle検索を実行します
Thread.sleep(1000)は、Qiitaに貼る画像をキャプチャーするためのWait用です。

SeleniumExample.java
package selenium;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumExample {

  public static void main(String[] args) throws InterruptedException {

    // ChromeDriverまでのパスを設定する
    System.setProperty("webdriver.chrome.driver", "selenium/chromedriver/2.40/chromedriver");

    // Chromeドライバーインスタンスを作成する
    WebDriver driver = new ChromeDriver();

    // Google.comにアクセスする
    driver.get("https://www.google.com");

    // 表示しているページのTitleを出力する
    System.out.println("Page title is: " + driver.getTitle());

    Thread.sleep(1000);

    // 検索ワード入力エレメントに、検索ワードを渡して、submitする
    WebElement searchElement = driver.findElement(By.name("q"));
    searchElement.sendKeys("Cheese!");

    Thread.sleep(1000);

    searchElement.submit();

    // ページが更新するまで待つ(Timeoutは10秒)
    new WebDriverWait(driver, 10)
        .until((ExpectedCondition<Boolean>) webDriver -> webDriver.getTitle().toLowerCase().startsWith("cheese!"));

    // ページ更新後のTitleを出力する
    System.out.println("Page title is: " + driver.getTitle());

    Thread.sleep(1000);

    // ブラウザーを閉じる
    driver.quit();
  }
}

実行するとChromeが立ち上がり検索を実行し、コンソールには検索前後のTitleが出力されたので、Seleniumからブラウザーを制御して情報が取れることが確認できた。


(Chromeが自動でアクティブにならないので自分でChromeに切り替えた)

次に、ChromeDriverのサイトにあるGetting startedのControlling ChromeDriver's lifetime を元にJUnitでテストケースを書いてみた

(公式サンプルのSelenium-Serverの定義部分は削除しています)

ChromeTest.java
package selenium;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ChromeTest {

  private WebDriver webDriver;

  @Before
  public void createDriver() {
    System.setProperty("webdriver.chrome.driver", "selenium/chromedriver/2.40/chromedriver");
    webDriver = new ChromeDriver();
  }

  @After
  public void quitDriver() {
    webDriver.close();
  }

  @Test
  public void testGoogle() {
    webDriver.get("https://www.google.com");
    assertThat(webDriver.getTitle(), is("Google"));
  }

  @Test
  public void testGoogleSearch() {
    webDriver.get("https://www.google.com");

    WebElement searchElement = webDriver.findElement(By.name("q"));
    searchElement.sendKeys("selenium");
    searchElement.submit();

    // ページが更新するまで待つ(Timeoutは10秒)
    new WebDriverWait(webDriver, 10)
        .until((ExpectedCondition<Boolean>) webDriver -> webDriver.getTitle().toLowerCase().startsWith("selenium"));

    assertThat(webDriver.getTitle(), is("selenium"));
  }
} 

testGoogleSearchメソッドが失敗しました。
titleが想定通りでは無かったので、 assertThat(webDriver.getTitle(), is("selenium"));assertThat(webDriver.getTitle(), is("selenium - Google 検索")); に変えて再度実行します。

無事、成功しました。

まとめ

Selenium clientとDriverがあれば、比較的簡単にブラウザーを使ったテストコードが書けることがわかりました。

実際には、CIツールと連携する。Selenium-Serverを導入したり、マルチブラウザにも対応すること、テストコードをできる限り簡単に用意する方法などを検討する必要はありますが、少しづつ進めていきたいと思います。