JavaでSeleniumを使って自動UIテストをする方法

はじめに

こんにちは!さいけです。

今回は「JavaでSeleniumを使って自動UIテストをする方法」を紹介します!

JavaでSeleniumを使って自動UIテストをする方法

Seleniumとは?

まず、Seleniumについて簡単に説明します。

Seleniumとは、webブラウザの自動操作を行えるライブラリです。

利用用途は様々ですが、主にテストの自動化に用いられます。

利用環境

本記事で利用する環境は以下です。

  • MacOS Catalina 10.15.2
  • IntelliJ IDEA 2019.3.1
  • SpringBoot 2.2.2
  • Java 1.8
  • Gradle 6.0.1
  • Google Chrome 79

利用準備

Selenuim Client (java)を依存関係に追加する

以下のmvnrepositoryからお好きなversionを指定して、Gradleの依存関係に追加します

Maven Repository: org.seleniumhq.selenium » selenium-java

本記事では、3.141.59を利用するので、以下を追加します。

implementation 'org.seleniumhq.selenium:selenium-java:3.141.59'

ChromeDriverをダウンロードする

以下リンクから、利用するChoromeバージョンと同じバージョンのDriverをダウンロードします。

Downloads - ChromeDriver - WebDriver for Chrome
WebDriver for Chrome

本記事では、Chromeバージョンが79なので、ChoromeDriver79をzipでダウンロードします。

また、MacOSなのでchromedriver_mac64.zipをダウンロードします。

ダウンロードを行いzipの解凍をしたら、プロジェクトの適当な場所にchromedriverを配置します。

本記事では画像のとおりに配置しました。

テストを書いてみる

当ブログに対するテストを書きました。

実施するUIテストは以下となります。

  • ブログホームのページタイトルが「さいけの技術ブログ」と表示されているか検証
  • ブログホームの技術タブをクリックし技術ページに遷移するか検証

コードは以下です。

package com.example.javaselenium;

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 java.util.concurrent.TimeUnit;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class SeleniumSampleTest {

    private WebDriver webDriver;

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

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

    @Test
    public void 正常系_表示_ページタイトル() {
        //指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // 検証
        assertThat(webDriver.getTitle(), is("さいけの技術ブログ"));
    }

    @Test
    public void 正常系_遷移_技術ページ() {
        //指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // タブの「技術」要素を取得し、クリックする
        WebElement webElement = webDriver.findElement(By.id("menu-item-37"));
        webElement.click();

        // 検証
        assertThat(webDriver.getTitle(), is("技術 – さいけの技術ブログ"));
        assertThat(webDriver.getCurrentUrl(), is("https://saikeblog.com/category/%e6%8a%80%e8%a1%93/"));
    }
}

テストを実行してみる

テストの実行をしてみます。

通りました!

今度は実行結果と期待値をずらして、テストが落ちるか検証してみます。

書き換えるテストケースは「正常系_遷移_技術ページ()」で、以下のようにassertThatを書き換えます。

assertThat(webDriver.getTitle(), is("技術 – さいけの技術ブログ"));
↓
assertThat(webDriver.getTitle(), is("さいけの技術ブログ"));

遷移したページタイトルと期待しているページタイトルは違うので、落ちるはずです。

ちゃんと落ちました!

👍🎉

おまけ

おまけですが、表示、整合、遷移、動作を担保するテストケースをざっと書いてみました。

以下、サンプルコードです。参考にしてみてください!

package com.example.javaselenium;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class SeleniumChromeTest {

    private WebDriver webDriver;

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

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

    @Test
    public void 正常系_表示_ページタイトル() {
        //指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // 検証
        assertThat(webDriver.getTitle(), is("さいけの技術ブログ"));
    }

    @Test
    public void 正常系_表示_コピーライト() {
        //指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // タブの「技術」要素を取得し、クリックする
        WebElement webElement = webDriver.findElement(By.className("source-org"));

        // 現在の年を取得する
        final int year= LocalDateTime.now().getYear();

        // 検証
        assertThat(webElement.getText(), is("Copyright © " + year + " さいけの技術ブログ All Rights Reserved."));
    }

    @Test
    public void 正常系_整合_URL() {
        //指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // 検証
        assertThat(webDriver.getCurrentUrl(), is("https://saikeblog.com/"));
    }

    @Test
    public void 正常系_遷移_技術ページ() {
        //指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // タブの「技術」要素を取得し、クリックする
        WebElement webElement = webDriver.findElement(By.id("menu-item-37"));
        webElement.click();

        // 検証
        assertThat(webDriver.getTitle(), is("技術 – さいけの技術ブログ"));
        assertThat(webDriver.getCurrentUrl(), is("https://saikeblog.com/category/%e6%8a%80%e8%a1%93/"));
    }

    @Test
    public void 正常系_動作_検索() {
        //指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // 検索ボックス要素にjavaを入力し検索する
        WebElement webElement = webDriver.findElement(By.name("s"));
        webElement.sendKeys("java");
        webElement.submit();

        // 検証
        assertThat(webDriver.getTitle(), is("“java” の検索結果 – さいけの技術ブログ"));
        assertThat(webDriver.getCurrentUrl(), is("https://saikeblog.com/?s=java"));
    }


    @Test
    public void 正常系_動作_ページング_次へボタン() {
        // 指定したURLに遷移する
        webDriver.get("https://saikeblog.com");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // 画面下部にスクロールするjavascriptを実行
        JavascriptExecutor javascriptExecutor = (JavascriptExecutor) webDriver;
        javascriptExecutor.executeScript("window.scrollTo(0, document.body.scrollHeight);");

        // 「次のページ」要素をクリックする
        WebElement webElement = webDriver.findElement(By.className("next"));
        webElement.click();

        // 検証
        assertThat(webDriver.getCurrentUrl(), is("https://saikeblog.com/page/2/"));
    }

    @Test
    public void 正常系_動作_ページング_前へボタン() {
        // 指定したURLに遷移する
        webDriver.get("https://saikeblog.com/page/2/");

        // 最大5秒間、ページが完全に読み込まれるまで待つ
        webDriver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

        // 画面下部にスクロールするjavascriptを実行
        JavascriptExecutor javascriptExecutor = (JavascriptExecutor) webDriver;
        javascriptExecutor.executeScript("window.scrollTo(0, document.body.scrollHeight);");

        // 「次のページ」要素をクリックする
        WebElement webElement = webDriver.findElement(By.className("prev"));
        webElement.click();

        // 検証
        assertThat(webDriver.getCurrentUrl(), is("https://saikeblog.com/"));
    }
} 

おわりに

今回は、「JavaでSeleniumを使って自動UIテストをする方法」の紹介をしました。

UIテストを自動化することによって、都度行うリグレッションテストなどを効率化することができそうです。

また、Seleniumでは色々な操作ができます。

クイックリファレンスがあるので、興味がある方は以下を参照してみてください。

Selenium API(逆引き)
Selenium APIを目的別に紹介します(Selenium RCのAPIは除く)。言語別にそれぞれ使い方ページにリンクが張られており目的別に利用したいメソッドを探すことが出来ます。

今後、node.js + mocha編も書こうかと思います〜\(^o^)/

では〜

コメント

タイトルとURLをコピーしました