68
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Java製SeleniumラッパーのSelenideを使ってみた

Posted at

Selenium勉強会@サイボウズに行ってきました #selenium_cybozu
の記事で

Selenideの話
 Selenide == Javaで書かれたSeleniumクライアントラッパー

というのを見つけてGroovy製のGebと比較したいなと思い、使ってみました。

Selenideについて

公式はここ。http://selenide.org/

Selenide is a wrapper for Selenium WebDriver that brings the following advantages:

Concise API for tests
Ajax support
True Page Objects
jQuery-style selectors

You don't need to think how to shutdown browser, handle timeouts or write monstrous code!
Concentrate on business logic!

gradle dependencies を使って、Selenideの依存関係を確認してみると各種driverも入ってることがわかる。

+--- com.codeborne:selenide:2.23
|    +--- com.google.guava:guava:18.0
|    +--- org.seleniumhq.selenium:selenium-java:2.47.1
|    |    +--- org.seleniumhq.selenium:selenium-chrome-driver:2.47.1 -> 2.48.2
|    |    |    \--- org.seleniumhq.selenium:selenium-remote-driver:2.48.2
|    |    |         +--- cglib:cglib-nodep:2.1_3
|    |    |         +--- com.google.code.gson:gson:2.3.1
|    |    |         +--- org.seleniumhq.selenium:selenium-api:2.48.2
|    |    |         |    +--- com.google.guava:guava:18.0
|    |    |         |    +--- com.google.code.gson:gson:2.3.1
|    |    |         |    \--- org.apache.httpcomponents:httpclient:4.5.1 (*)
|    |    |         +--- org.apache.httpcomponents:httpclient:4.5.1 (*)
|    |    |         +--- com.google.guava:guava:18.0
|    |    |         +--- org.apache.commons:commons-exec:1.3
|    |    |         +--- net.java.dev.jna:jna:4.1.0
|    |    |         \--- net.java.dev.jna:jna-platform:4.1.0
|    |    |              \--- net.java.dev.jna:jna:4.1.0
|    |    +--- org.seleniumhq.selenium:selenium-edge-driver:2.47.1
|    |    |    +--- org.seleniumhq.selenium:selenium-remote-driver:2.47.1 -> 2.48.2(*)
|    |    |    +--- commons-io:commons-io:2.4
|    |    |    \--- org.apache.commons:commons-exec:1.3
|    |    +--- org.seleniumhq.selenium:selenium-firefox-driver:2.47.1
|    |    |    +--- org.seleniumhq.selenium:selenium-remote-driver:2.47.1 -> 2.48.2(*)
|    |    |    +--- commons-io:commons-io:2.4
|    |    |    \--- org.apache.commons:commons-exec:1.3
|    |    +--- org.seleniumhq.selenium:selenium-ie-driver:2.47.1
|    |    |    +--- net.java.dev.jna:jna:4.1.0
|    |    |    +--- net.java.dev.jna:jna-platform:4.1.0 (*)
|    |    |    \--- org.seleniumhq.selenium:selenium-remote-driver:2.47.1 -> 2.48.2(*)
|    |    +--- org.seleniumhq.selenium:selenium-support:2.47.1
|    |    |    \--- org.seleniumhq.selenium:selenium-remote-driver:2.47.1 -> 2.48.2(*)
|    |    \--- org.seleniumhq.selenium:selenium-leg-rc:2.47.1
|    |         \--- org.seleniumhq.selenium:selenium-remote-driver:2.47.1 -> 2.48.2(*)
|    \--- commons-codec:commons-codec:1.10

環境

selenide2.23
Java8
SpringBoot1.2.7
Doma2.5.0
H2
Gradle2.8

SpringBoot+Doma2+Gradleを試してみた。」のアプリを、ライブラリを最新化して使いまわしてます。

参考までにGebで実装したものはこちら。
SpringBootで作ったRestAPI/Webアプリのテストを書いてみた

実装

ソースはこちら。
https://github.com/nyasba/domaboot.git

Gebのときと同様PageObjectパターンで実装してみました。

メインページのPageObject

お作法はGebと微妙に違いますが、そんなに困ることなく移植できました。

MainPage.java
package com.example.web.selenide.page;

import com.codeborne.selenide.Selenide;
import org.openqa.selenium.By;

/**
 * メインページ
 */
public class MainPage {

    private static final String URL = "http://localhost:8888/customers";

    public static void open(){
        Selenide.open(URL);
    }

    public static String title(){
        return Selenide.title();
    }

    public static int 登録件数(){
        return Selenide.$$(Selenide.$(By.id("customer-list")).find("tbody"),"tr").size();
    }

    public static void 姓は(String lastName){
        Selenide.$(By.id("lastName")).setValue(lastName);
    }
    public static void 名は(String firstName){
        Selenide.$(By.id("firstName")).setValue(firstName);
    }

    public static void で登録する(){
        Selenide.$(By.id("register")).click();
    }

    public static String 名前(int index){
        return Selenide.$(By.id("lastName" + String.valueOf(index))).getText()
                +  Selenide.$(By.id("firstName" + String.valueOf(index))).getText();
    }

    public static void 編集ボタンを押す(int index){
        Selenide.$(By.id("edit" + String.valueOf(index))).click();
    }

    public static void 削除ボタンを押す(int index){
        Selenide.$(By.id("delete" + String.valueOf(index))).click();
    }

}

編集ページのPageObject

EditPage.java
package com.example.web.selenide.page;

import com.codeborne.selenide.Selenide;
import org.openqa.selenium.By;

/**
 * 編集ページ
 */
public class EditPage {

    public static String title(){
        return Selenide.title();
    }

    public static void 姓は(String lastName){
        Selenide.$(By.id("lastName")).setValue(lastName);
    }
    public static void 名は(String firstName){
        Selenide.$(By.id("firstName")).setValue(firstName);
    }

    public static void で更新する(){
        Selenide.$(By.id("submit")).click();
    }

    public static void やっぱり戻る(){
        Selenide.$(By.id("goToTop")).click();
    }
}

テストシナリオ

流れ。

  1. @BeforeClassでテスト対象アプリを起動し、Chromeを使う設定を追加
    (デフォルトはFirefoxになり、Firefoxだとdriverの設定は不要)
  2. @Testでテスト実行
  3. @Afterでテストで登録したデータをすべて削除
  4. @AfterClassでブラウザを閉じる
CustomerWebTest.java
package com.example.web.selenide;

import com.codeborne.selenide.Configuration;
import com.codeborne.selenide.WebDriverRunner;
import com.example.App;
import com.example.web.selenide.page.EditPage;
import com.example.web.selenide.page.MainPage;
import org.junit.*;
import org.junit.runners.MethodSorters;

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

public class CustomerWebTest {

    @BeforeClass
    public static void setUpClass() {

        // テスト対象アプリの起動
        App.main(new String[]{
                "--server.port=8888",
                "--spring.profiles.active=test"
        });

        // 何も指定しない場合はFirefoxになる
        Configuration.browser = WebDriverRunner.CHROME;
        System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe");
    }

    @After
    public void tearDown() {
        // 登録されてるデータを全部消す
        for(int i = MainPage.登録件数(); i > 0; i--){
            System.out.println("削除" + String.valueOf(i));
            MainPage.削除ボタンを押す(i);
        }
    }


    @AfterClass
    public static void tearDownClass() {
        WebDriverRunner.closeWebDriver();
    }

    @Test
    public void 剛田たけしとどらえもんを登録する() {
        MainPage.open();
        assertThat(MainPage.登録件数(), is(0));

        MainPage.姓は("剛田");
        MainPage.名は("たけし");
        MainPage.で登録する();

        assertThat(MainPage.登録件数(), is(1));
        assertThat(MainPage.名前(1), is("剛田たけし"));

        MainPage.姓は("どら");
        MainPage.名は("えもん");
        MainPage.で登録する();

        assertThat(MainPage.登録件数(), is(2));
        assertThat(MainPage.名前(2), is("どらえもん"));

    }

    @Test
    public void 剛田たけしで登録した後にきれいなジャイアンに変更する() {
        MainPage.open();
        MainPage.姓は("剛田");
        MainPage.名は("たけし");
        MainPage.で登録する();

        MainPage.編集ボタンを押す(1);

        EditPage.姓は("きれいな");
        EditPage.名は("ジャイアン");
        EditPage.で更新する();

        assertThat(MainPage.title(), is("顧客管理システム"));
        assertThat(MainPage.名前(1), is("きれいなジャイアン"));
    }

    @Test
    public void 剛田たけしで登録した後に変更しようとしてやっぱり戻る() {
        MainPage.open();
        MainPage.姓は("剛田");
        MainPage.名は("たけし");
        MainPage.で登録する();

        MainPage.編集ボタンを押す(1);

        EditPage.やっぱり戻る();

        assertThat(MainPage.名前(1), is("剛田たけし"));
    }

    @Test
    public void 剛田たけしで登録した後に削除する() {
        MainPage.open();
        MainPage.姓は("剛田");
        MainPage.名は("たけし");
        MainPage.で登録する();

        assertThat(MainPage.登録件数(), is(1));
        MainPage.削除ボタンを押す(1);

        assertThat(MainPage.登録件数(), is(0));
    }
}

Gebでは各テストをつなげて1つのテストシナリオにしていたのですが、JUnitでテストの順序を指定する方法がうまくいきませんでした。(@FixMethodOrderとか試したのですが)

ただ、そこは本質じゃないので、それぞれのテストを独立したものに書き換えたことによりGebと構成は少し変わってます

感想

SelenideはJava製ということがあって、Javaエンジニアの方が気軽に使えるというのが一番いいところですね。Groovy(Spock)の知識が必要なGebと比べると敷居は低いと思います

簡単なところまでしか試していませんが、機能的にも遜色ないとおもいます。

(もしかすると何か解決方法があるのかもしれませんが)Gebだとページが遷移していくときにIDEの補完機能が効かないときがあり、Selenideはそういうことはありませんでした。

#個人的にはSpock+SelenideでCustomerWebTestの可読性をあげるのもアリかなと思いました。

おわり。

68
70
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?