かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その30 )( Geb を 2.0 へバージョンアップする+Firefox headless モードを使用する )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その29 )( Geb をインストールする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Geb の 2.0 がリリースされたのでバージョンアップします。
    • geckodriver.exe の場所を jvm のオプション -Dwebdriver.gecko.driver= で指定するのではなく System.setProperty("webdriver.gecko.driver", "...") で指定するよう変更します。
    • Firefox に headless モードがあるようなので、headless モードを使用するよう設定を変更します。

参照したサイト・書籍

  1. Geb - Very Groovy Browser Automation
    http://www.gebish.org/

  2. Headless mode
    https://developer.mozilla.org/en-US/Firefox/Headless_mode

  3. Disable HttpClient logging
    https://stackoverflow.com/questions/4915414/disable-httpclient-logging

  4. How do I disable Firefox logging in Selenium using Geckodriver?
    https://stackoverflow.com/questions/41387794/how-do-i-disable-firefox-logging-in-selenium-using-geckodriver

目次

  1. Geb を 2.0-rc-1 → 2.0 へバージョンアップする
  2. geckodriver.exe の場所は System.setProperty("webdriver.gecko.driver", "...") で指定する
  3. Firefox headless モードを使用する
    1. GebConfig.groovy を変更する
    2. 動作確認
    3. 大量に出力される DEBUG ログ [Forwarding ... on session ... to remote] DEBUG org.apache.http を抑制する
    4. Marionette DEBUG のログを抑制する

手順

Geb を 2.0-rc-1 → 2.0 へバージョンアップする

build.gradle の以下の点を変更します。

dependencies {
    ..........
    def seleniumVersion = "3.6.0"

    ..........

    // for Geb + Spock
    testCompile("org.gebish:geb-spock:2.0")
    testCompile("org.seleniumhq.selenium:selenium-firefox-driver:${seleniumVersion}")
    testCompile("org.seleniumhq.selenium:selenium-support:${seleniumVersion}")
    testCompile("org.seleniumhq.selenium:selenium-api:${seleniumVersion}")
    testCompile("org.seleniumhq.selenium:selenium-remote-driver:${seleniumVersion}")
}
  • org.gebish:geb-spock のバージョン番号を 2.0-rc-12.0 に変更します。
  • def seleniumVersion = "3.6.0" を追加し、selenium のモジュールのバージョン番号を ${seleniumVersion} で指定するよう変更します。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

Tomcat を起動した後、test, gebTest タスクを実行して問題ないことを確認します(画面キャプチャは省略します)。この後もテストを繰り返すので Tomcat は起動したままにします。

geckodriver.exe の場所は System.setProperty("webdriver.gecko.driver", "...") で指定する

前回の記事では geckordriver.exe を build.gradle の gebTest タスクと、IntelliJ IDEA の「Run」-「Edit Configurations...」メニューで開いた先の JUnit の設定のところに記述しましたが、GebConfig.groovy に System.setProperty("webdriver.gecko.driver", "...") で定義すれば利用可能になることが分かったので、設定を変更します。

src/test/resources/GebConfig.groovy を以下のように変更します。

import org.openqa.selenium.firefox.FirefoxDriver

driver = {
    System.setProperty("webdriver.gecko.driver", "C:/geckodriver/0.19.0/geckodriver.exe")
    new FirefoxDriver()
}
baseUrl = "http://localhost:8080"
waiting {
    timeout = 15
}

build.gradle の gebTest を以下のように変更します。

test {
    jvmArgs = ['-Dspring.profiles.active=unittest']
    exclude "geb/**"
}

task gebTest(type: Test) {
    jvmArgs = ['-Dspring.profiles.active=unittest']
    exclude "ksbysample/**"
}
  • jvmArgs の指定を '-Dwebdriver.gecko.driver=C:/geckodriver/0.19.0/geckodriver.exe' を削除して test タスクと同じにします。

IntelliJ IDEA のメインメニューから「Run」-「Edit Configurations...」を選択して「Run/Debug Configurations」ダイアログを表示した後、「JUnit」の「VM Options」から -Dwebdriver.gecko.driver=C:/geckodriver/0.19.0/geckodriver.exe を削除します。

f:id:ksby:20171028080101p:plain

動作確認します。

最初に clean タスク → Rebuild Project → build タスクを実行して BUILD SUCCESSFUL のメッセージが出力されることを確認します(画面キャプチャは省略します)。

次に gebTest タスクを実行すると Firefox が起動し、テストは成功します。

f:id:ksby:20171028080601p:plain

最後に src/test/groovy/geb/gebspec/SimpleTestSpec.groovy を開き、左側のアイコンから Run '動作確認用()' を選択します。

f:id:ksby:20171028081146p:plain

こちらも Firefox が起動し、テストは成功します。

f:id:ksby:20171028082241p:plain

Firefox headless モードを使用する

Firefox に headless モードが実装されているらしいので、そちらを使うように設定してみます。

GebConfig.groovy を変更する

src/test/resources/GebConfig.groovy を以下のように変更します。

import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxOptions

driver = {
    System.setProperty("webdriver.gecko.driver", "C:/geckodriver/0.19.0/geckodriver.exe")
    FirefoxOptions firefoxOptions = new FirefoxOptions()
    firefoxOptions.setHeadless(true)
    new FirefoxDriver(firefoxOptions)
}
baseUrl = "http://localhost:8080"
waiting {
    timeout = 15
}
  • 以下の2行を追加します。
    • FirefoxOptions firefoxOptions = new FirefoxOptions()
    • firefoxOptions.setHeadless(true)
  • new FirefoxDriver() の引数に firefoxOptions を追加します。

動作確認

動作確認します。

最初に clean タスク → Rebuild Project → build タスクを実行して BUILD SUCCESSFUL のメッセージが出力されることを確認します(画面キャプチャは省略します)。

次に gebTest タスクを実行してみると Firefox の画面は表示されず、テストは成功します。ただし DEBUG ログが大量に出ます。。。 これは出来れば出ないようにしたいですね。

f:id:ksby:20171028124025p:plain

DEBUG メッセージに対応する前に、うまく動いているのかちょっと分かりづらいので、テストの内容を少し変更してみます。

src/test/groovy/geb/page/inquiry/InquiryInput01Page.groovy を以下のように変更します。

package geb.page.inquiry

import geb.Page

class InquiryInput01Page extends Page {

    static url = "/inquiry/input/01"
    static at = { title == "入力フォーム - 入力画面1" }
    static content = {
        btnNext { $(".js-btn-next") }
    }

}
  • static content { ... } を追加し、その中に btnNext { $(".js-btn-next") } を記述します。

src/test/groovy/geb/gebspec/SimpleTestSpec.groovy を以下のように変更し、最後でテストが失敗するようにします。

package geb.gebspec

import geb.page.inquiry.InquiryInput01Page
import geb.spock.GebSpec

class SimpleTestSpec extends GebSpec {

    def "動作確認用"() {
        given: "入力画面1へアクセスする"
        to InquiryInput01Page
        waitFor { at InquiryInput01Page }
        $("#form-group-name .js-errmsg").displayed == false

        when: "何も入力せずに「次へ」ボタンをクリックする"
        btnNext.click(InquiryInput01Page)

        then: "「お名前(漢字)」の必須チェックエラーのメッセージが表示される"
        $("#form-group-name .js-errmsg").displayed == true
//        $("#form-group-name .js-errmsg").text() == "お名前(漢字)を入力してください"
        $("#form-group-name .js-errmsg").text() == "エラーです"
    }

}

gebTest タスクを実行してみると今度はエラーになりました。Spock はエラーメッセージが分かりやすくていいですね。

f:id:ksby:20171028125357p:plain

src/test/groovy/geb/gebspec/SimpleTestSpec.groovy を以下のように変更し、今度は成功するようにします。

package geb.gebspec

import geb.page.inquiry.InquiryInput01Page
import geb.spock.GebSpec

class SimpleTestSpec extends GebSpec {

    def "動作確認用"() {
        given: "入力画面1へアクセスする"
        to InquiryInput01Page
        waitFor { at InquiryInput01Page }
        $("#form-group-name .js-errmsg").displayed == false

        when: "何も入力せずに「次へ」ボタンをクリックする"
        btnNext.click(InquiryInput01Page)

        then: "「お名前(漢字)」の必須チェックエラーのメッセージが表示される"
        $("#form-group-name .js-errmsg").displayed == true
        $("#form-group-name .js-errmsg").text() == "お名前(漢字)を入力してください"
//        $("#form-group-name .js-errmsg").text() == "エラーです"
    }

}

gebTest タスクを実行してみると今度は成功します。headless モードでも問題なく動いているようです。

f:id:ksby:20171028130043p:plain

大量に出力される DEBUG ログ [Forwarding ... on session ... to remote] DEBUG org.apache.http を抑制する

何か情報がないか Google で検索すると、stackoverflow の以下の QA を見つけました。

これを読むと logback.xml があれば抑制できるようです。

src/test/resources の下に logback.xml を新規作成し、以下の内容を記述します。色々試してみたところ <logger .../> の定義がなくても logback.xml があれば DEBUG ログを抑制できるようです。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
        Geb+Spock で Firefox を headless モードで動かした時に大量に以下の DEBUG ログ
        が出力されるのを抑制するために作成しているファイルである。ファイルがあればログを抑
        制できるので、特に logger の定義は記述していない。

        [Forwarding ... on session ... to remote] DEBUG org.apache.http
     -->
</configuration>

gebTest タスクを実行してみると [Forwarding ... on session ... to remote] DEBUG org.apache.http の DEBUG メッセージは出力されました。ただし、まだ Marionette DEBUG というログが出力されています。

f:id:ksby:20171028133928p:plain

Marionette DEBUG のログを抑制する

Google で検索していろいろ見たのですが、stackoverflow の以下の QA を見て解決しました。

geckodriver.exe を配置した C:\geckodriver\0.19.0 の下に geckodriver.bat を新規作成し、以下の内容を記述します。

@echo off
C:\geckodriver\0.19.0\geckodriver.exe --log info %* > NUL 2>&1

src/test/groovy/GebConfig.groovy を以下のように変更します。

import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxOptions

driver = {
    System.setProperty("webdriver.gecko.driver", "C:/geckodriver/0.19.0/geckodriver.bat")
    FirefoxOptions firefoxOptions = new FirefoxOptions()
    firefoxOptions.setHeadless(true)
    new FirefoxDriver(firefoxOptions)
}
baseUrl = "http://localhost:8080"
waiting {
    timeout = 15
}
  • System.setProperty("webdriver.gecko.driver", "...") の第2引数に設定していたプログラム名を C:/geckodriver/0.19.0/geckodriver.exeC:/geckodriver/0.19.0/geckodriver.bat に変更します。

gebTest タスクを実行すると Marionette DEBUG のログは全く出力されなくなりました。

f:id:ksby:20171028143338p:plain

履歴

2017/10/28
初版発行。