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

ガベージコレクション - Wikipedia



ここでふと、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)が不要になったため、メモリの使用は更に削減できた。

Xvfb - Wikipedia


これで格安VPSサーバでも引き続き、負荷の高いテストを行えると信じたい。