SOY CMS / Shopの開発で、Jenkinsを利用してテストの自動化を行っている。
※詳しい構成は下記のリンク先の記事に記載がある。
さくらVPSにJenkinsを入れて、Selenium + php-webdriverを動かせるようにする
機能を追加する度に負荷の高いテストコードを追加し続け、
気がついたら、一回のビルドの所要時間が5時間を超えていた。
1日3回ぐらいJenkinsがテストを行ってくれるので、
1日15時間とテスト要因で人を雇ったらブラック企業として扱われてしまう程、Jenkinsにはお世話になっている。
上のダッシュボードのキャプチャを見るとバレてしまうけれども、
最近、Jenkinsのテストが通らなくなってきた。
エラー内容は下記の通りで、
PHP Fatal error: Uncaught Facebook\WebDriver\Exception\UnknownServerException: unknown error: session deleted because of page crash from tab crashed
テストで利用しているChromeがクラッシュするらしい。
Jenkinsを設置しているVPSサーバでのメモリの使い過ぎか?
負荷の高いテストは行いたいので、どうしようかと悩み、
一回のビルドを小刻みにして都度、php-webdriverのquit()を実行してプロセスを終了してみたり、
プロセスを終了した後、PHPのgc_collect_cycles関数で、ガベージコレクション(GC)をしてみたけれども改善ならず…
PHP: gc_collect_cycles - Manual
ここでふと、Chromeの方でメモリの使用を省力化するモードがあったなと。
というわけで、省力化モードのヘッドレスChromeをJenkins(詳しくはphp-webdriver)で使用できるか?調べてみた。
先にヘッドレスChromeについて触れておくと、
ヘッドレス環境という画面のない環境でChromeを立ち上げることで、画面描写(GUI)に関するリソースを省略することが出来る。
GUIへのリソースを減らすことで、サーバのメモリの負担を減らすことができる。
ヘッドレス Chrome ことはじめ | Web | Google Developers
VPSサーバ上でテストを行っているので、ヘッドレスChromeで全然問題ない。
というわけで、
今までの仮想デスクトップを立ち上げて、Chromeを立ち上げテストを行うコードから、ヘッドレスChromeでテストを行うコードへの変更を見てみると、
※以前のコードは下記のリンク先のページに記載がある
php-webdriverで指定のフォームに値を入力してみる
今までのコード
<?php require_once 'autoload.php'; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\WebDriverExpectedCondition; use Facebook\WebDriver\WebDriverBy; $host = "http://example.com:4444/wd/hub"; $caps = DesiredCapabilities::chrome(); $driver = RemoteWebDriver::create($host, $caps); //実際のテストコードを書く
このコードを、
<?php require_once 'autoload.php'; use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\WebDriverExpectedCondition; use Facebook\WebDriver\WebDriverBy; $host = "http://example.com:4444/wd/hub"; $caps = DesiredCapabilities::chrome(); //ヘッドレスChromeを使用するための手続き $options = new ChromeOptions(); $options->addArguments(['--headless']); $caps->setCapability(ChromeOptions::CAPABILITY, $options); $driver = RemoteWebDriver::create($host, $caps); //実際のテストコードを書く
上記のコードのように、ChromeOptionsを読み込み、ヘッドレスChromeを使用するための手続きを追加する。
ChromeOptions等の詳しい話は下記のページに記載がある。
ChromeOptions · facebook/php-webdriver Wiki
テストコードも追加して実行してみたら、エラーが発生せずテストが開始した。
※実際の環境ではChromeではなく、Chromiumを利用しているが問題はなかった。
今回のヘッドレスChromeによって、
以前、VPS上で必ず実行していなければならない仮想デスクトップ(Xvfb)が不要になったため、メモリの使用は更に削減できた。
これで格安VPSサーバでも引き続き、負荷の高いテストを行えると信じたい。