前回「geckodriver(SeleniumのWebDriver)をMavenコマンド使ってパス上に配置する方法」(やや強引なドリブルをするやり方)を紹介しましたが・・・WebDriver毎の実行ファイルをダウンロードしてSeleniumが参照可能なパスへ自動でインストールしてくれるライブラリ(WebDriverManager)があったので、今回はそちらの使い方を紹介したいと思います!!
Note:
2017/4/2 :追記
1.6.2がリリースされたので記載を修正しました。1.6.2より、認証付きProxy Serverを介したインターネットアクセスがサポートされました!!
検証バージョン
- WebDriverManager 1.6.2
- Selenide 4.3
- Selenium 3.0.1 (Selenide 4.3の依存バージョン)
- geckodriver 0.14.0
- Firefox 52.0.1 (64 ビット)
- IntelliJ IDEA 2016.3.5
- OS: Mac
実践アプリ
本エントリーで記載した内容は、以下のアプリケーションで実践しています。以降の説明も、このアプリケーションをベースに説明していきます。
Note:
原因はわかっていませんが、たまにテストが失敗することがあります・・・(時間がある時に調査してみます)
WebDriverManagerってなにもの?
具体的な使い方を紹介する前に、WebDriverManagerが何をしてくれるのか簡単に紹介しておきましょう。WebDriverManagerは、具体的には以下の2つの処理を行います。
-
WebDriver
が使用する実行ファイルのダウンロード&アーカイブファイルの解凍(所定ディレクトリへの配置) - 実行ファイルのパスを指定するシステムプロパティ(例:
webdriver.gecko.driver
)の設定
Note:
デフォルトでは、テスト実行時の最新バージョンがインストールされます。すでに同一バージョンの実行ファイルがインストールされていればダウンロード処理はスキップし、「実行ファイルのパスを指定するシステムプロパティ」の設定処理だけ行われます。
実行ファイルの配置先
デフォルトでは、実行ファイルは「$HOME/.m2/repository/webdriver」配下に「$HOME/.m2/repository/webdriver/{ドライバ名}/{OS}/{バージョン}/{実行ファイル名}」というルールで格納されます。以下は、Forefoxを使う際に必要になるgeckodriver
の配置例になります。
$ pwd
/Users/xxx/.m2/repository/webdriver
$ tree
.
└── geckodriver
└── macos
└── 0.14.0
└── geckodriver // ### 実行ファイル
サポートしているWebDriver実装
WebDriverManagerがサポートしているのは、以下の6つのWebDriver実装になります。
WebDriverクラス名 | 実行ファイルのパスを指定するシステムプロパティ |
---|---|
ChromeDriver |
webdriver.chrome.driver |
OperaDriver |
webdriver.opera.driver |
InternetExplorerDriver |
webdriver.ie.driver |
EdgeDriver |
webdriver.edge.driver |
PhantomJSDriver |
phantomjs.binary.path |
FirefoxDriver |
webdriver.gecko.driver |
Note:
Safariはサポートしていないみたいです・・・。
WebDriverManagerのインストール
WebDriverManagerのインストールは、WebDriverManagerのjarファイルをクラスパスに追加するだけです。以下は、Maven使用時のインストール方法になります。
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>1.6.2</version> <!-- 投稿時の最新バージョン -->
<scope>test</scope>
</dependency>
WebDriverManagerのセットアップ
WebDriverManagerは勝手に実行ファイルをインストールすることはありません。実行ファイルを自動でインストールしたい場合は、使用するWebDriver実装に対応するManagerクラスのメソッドを明示的に呼び出す必要があります。
// ...
import static com.codeborne.selenide.Configuration.*;
// ...
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class JpetstoreApplicationTests {
@LocalServerPort
private int port;
@BeforeClass
public static void setupWebDriverManager() {
FirefoxDriverManager.getInstance().setup(); // (1)
}
@Before
public void setupSelenide() {
browser = MARIONETTE; // (2)
timeout = TimeUnit.SECONDS.toMillis(10);
baseUrl = String.format("http://localhost:%d", port);
}
// ...
}
項番 | 説明 |
---|---|
(1) | WebDriver実装毎のManagerクラスに実装されているsetup メソッドを呼び出すと、WebDriverの実行ファイルがインストールされる。ここでは、FirefoxDriverを使う際に必要なgeckodriverをインストールしている。 |
(2) | Selenideが使用するブラウザ(WebDriver実装)の指定を行う。ここでは、FirefoxDriver(MARIONETTE)を指定している。 |
テストを実施してみる!!
テストケースを実行すると、以下のようなログが出力され、テスト実施前にWebDriverの実行ファイルがインストールされていることがわかります。
...
21:53:23.107 [main] INFO io.github.bonigarcia.wdm.Downloader - Downloading https://github.com/mozilla/geckodriver/releases/download/v0.14.0/geckodriver-v0.14.0-macos.tar.gz to /Users/xxx/.m2/repository/webdriver/geckodriver/macos/0.14.0/geckodriver-v0.14.0-macos.tar.gz
21:53:31.084 [main] INFO i.g.bonigarcia.wdm.BrowserManager - Exporting webdriver.gecko.driver as /Users/xxx/.m2/repository/webdriver/geckodriver/macos/0.14.0/geckodriver
...
デフォルトでは、テスト実行時の最新バージョンがインストールされますが、場合によっては最新バージョンだと正しく動作しないことがあります。本エントリで利用しているSelenide(Seleniumのラッパーライブラリ)だとgeckodriverの0.15.0(投稿時の最新版)だと正しく動作しないため、意図的にひとつ前の0.14.0を使用するようにしています。
ちなみに・・・1.6.2からHTTP通信はApache Components HttpClientを使うよう変更になっています。実践アプリでは@BeforeClass
を付与したメソッドでsetup
メソッドを呼び出している関係で、HttpClientの通信ログが大量に出力されるため、テスト用のlogback.xml
(logback-test.xml
)を用意しています。
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<logger name="org.apache.http" level="error"/>
<root level="info">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
WebDriverManagerのコンフィギュレーション
WebDriverManagerの動作は、Java APIとプロパティファイル(クラスパス直下のwebdrivermanager.properties
)を使用してコンフィギュレーションすることができます。
たとえば、使用するバージョンを固定化したい場合は・・・
- Java APIの場合
@BeforeClass
public static void setupWebDriverManager() {
FirefoxDriverManager.getInstance().version("0.14.0").setup();
}
- プロパティファイルの場合
wdm.geckoDriverVersion = 0.14.0
といった感じで、動作をカスタマイズすることができます。
GitHub API使用時に発生する403エラーの回避方法
WebDriver実装としてOperaDriverまたはFirefoxDriverを使用する場合は、実行ファイルをダウンロードする際にGitHub APIを使用する仕組みになっている関係で、IPアドレス単位の「API呼び出し回数制限」にひっかかり、403エラーが発生して実行ファイルがダウンロードができないケースがあります。時間をおけば制限が解除されダウンロードすることができますが、この事象を根本的に解決したい場合は、GitHub APIを呼び出す際にBasic認証を使用してGitHubアカウントの資格情報(ユーザ名とトークン or パスワードを指定してください。
ちなみに・・・セキュリティ的な観点からトークンを使うようにしましょう。なお、トークンは「New personal access token」で発行することができます(スコープは選択しなくてもOK)。
で・・・GitHubのユーザ名と発行したトークンは、
- システムプロパティ
- プロパティファイル(
webdrivermanager.properties
)
のいずれかに指定します。それぞれプロパティキーは以下の通りです。
プロパティキー | 説明 |
---|---|
wdm.gitHubTokenName |
GitHubのアカウント名 |
wdm.gitHubTokenSecret |
「New personal access token」で発行したトークン |
おそらくプロパティファイルはGitなどのVCSで管理することが多いと思うので、セキュリティの観点からいうとプロパティファイルではなくシステムプロパティとして指定する方がよいと思います。
本エントリーで紹介している実践アプリでも、Travis CI上でテストを実行する際には、Travis CI上の環境変数に資格情報を設定しておき、テスト実施を行うmvnコマンド実行時に環境変数から取得した値をシステムプロパティを介して連携するようにしています。
./mvnw -U package -Dwdm.gitHubTokenName=${WDM_GITHUB_USER} -Dwdm.gitHubTokenSecret=${WDM_GITHUB_TOKEN}
Proxy Serverを介したインターネット接続
インターネットに接続する際にProxy Serverを介す必要がある場合は、「HTTPS_PROXY」環境変数にProxy Serverの接続情報を指定する方法と、Java APIを使用して指定する方法が用意されており、
- 「HTTPS_PROXY」環境変数の場合
export HTTPS_PROXY=http://proxy.example.com:9999
- Java APIの場合
@BeforeClass
public static void setupWebDriverManager() {
FirefoxDriverManager.getInstance().proxy("http://proxy.example.com:9999").setup();
}
といった感じで指定することができます。
Note: 認証付きのProxy Serverを介したインターネット接続について
1.6.2から認証付きProxy Serverを介したインターネット環境でもWebDriverManagerのダウンロード機能がつかえるようになり、Proxy Serverのユーザ名とパスワードの指定は、以下の中から選ぶことができます。
HTTPS_PROXY
環境変数の設定値の中で指定。形式:「http://username:password@host:port
」HTTPS_PROXY_USER
とHTTPS_PROXY_PASS
環境変数に指定BrowserManager
のproxy(String)
、proxyUser(String)
、proxyPass(String)
メソッドの引数に指定
まとめ
前回「geckodriver(SeleniumのWebDriver)をMavenコマンド使ってパス上に配置する方法」(やや強引なドリブルをするやり方)を紹介してしまいましたが、WebDriverManagerを使用して実行ファイルをSeleniumにインストールする(認識させる)のがよさげです。1.6.2から「認証付きのProxy Serverを介したインターネット接続」がサポートされたので、職場環境への導入のハードルがなくなった!!