JUnit 5にTemporalyFolderに相当する機能がなかったため、自分のプロジェクトでは長らくJUnit4を使っていました。しかし5.4でTempDirが来たため、徐々にJUnit5に置き換えています。
その過程でSelenideを使った統合テストをJUnit5に置き換えたのですが、selenium-jupiterがなかなか便利でした。作業したリポジトリはこちらです。 ただ一筋縄に行かない部分もあるので、備忘録を残します:
SpringBootTestとSelenideとの噛みあわせ
SpringBootTestにはランダムなポートでアプリケーションサーバを起動する機能がありテストの並列実行に役立ちます。
またselenium-jupiterはSelenideをサポートしており、テストメソッドのパラメータに SelenideDriver
を指定するとインスタンスを作って注入してくれます。
さてSelenideにはbaseUrlという設定があり、Configuration.baseUrl
にURL文字列を指定しておくとSelenideDriver
インスタンス作成時に使ってくれます。
これによりテストメソッドではスキーマやドメイン名、ポート番号などを省略した相対URLを指定するだけで済むのですが。SelenideDriver
インスタンスは@BeforeEach
メソッドが実行されたタイミングで既に作成されているので以下のようにbaseUrl
を指定しても効いてくれません。
@LocalServerPort private int port; @BeforeEach void config() { Configuration.baseUrl = String.format("http://localhost:%d/", port); } @Test void test(SelenideDriver driver) { System.out.println(driver.config().baseUrl()); // デフォルトの http://localhost:8080/ になってしまう }
現状きれいに解決する方法が見当たらないので、テストメソッドでは相対URLではなく絶対URLを使うようにしています。
SpringBootTestするならDocker内ブラウザは使わないほうが良い
selenium-jupiterではDocker内のブラウザを使うこともできるのですが、ドキュメント末尾に注意書きがあるようにローカルにアプリケーションサーバを建てているときは一筋縄では行きません。DockerコンテナからDockerホスト(localhost)にHTTP接続をする必要があるのですが、ホスト名を解決する統一的な手法が存在しないのです。特にLinux環境ではホスト名ではなくIPアドレスを取得する必要があり、一度 ip addr show docker0|grep 'inet '|awk '{$1=$1};1'|cut -d ' ' -f 2|cut -d / -f 1
などの操作をしてシステムプロパティ経由でテストに対して渡す必要があり面倒です。baseUrl
が使えればホスト名構築処理を抽象クラスで集中管理できたのでまだマシだったのでしょうが……。
他にもブラウザで何らかの問題が起こったときのトラブルシュートが面倒ということもあり、SpringBootTestを使う場合はDocker内ブラウザは使用しないほうが良いのではと感じました。Travis CIなら安定版のChromeをCI環境にインストールする方法があるので、コンテナを使う必要性もあまりありません。