ブラウザテストに興味が出たので導入してみた
この記事でわかること
- Duskを動かすためのLaradockの設定
-
WORKSPACE_INSTALL_DUSK_DEPS=true
を設定
-
- Duskを動かす時のエラー回避法
-
APP_URL
合わせよう -
php artisan serve
実行しよう -
no-sandbox
オプションつけよう
-
- フロントがvue.jsのときでもDuskを動かす方法
-
waitFor
メソッドを使って対象DOMがロードされるまで待つ
-
筆者環境
OS: Windows10
WSL:Ubuntu22.04
バックエンド:Laravel 8.x on LaraDock
フロントエンド:vue.js
前提
すでにvue.jsでログインフォームだけ作成済み(後述)
Laradock側の修正
duskでのテスト実行では、Chromeブラウザ、ChromeDriverが必要。
最新のLaradockではDockerFileを変更しなくても、下記envだけ変更すれば標準でインストールできる。
- WORKSPACE_INSTALL_DUSK_DEPS=false
+ WORKSPACE_INSTALL_DUSK_DEPS=true
Laradockのほうの.envに反映
LaraDockでduskの環境を整えるという発想は、下記のサイトが参考になりました。
Laravel側の修正
dusk実行時の下記エラーを防ぐために、envのAPP_URLを変更する
1) Tests\Browser\ExampleTest::testBasicExample
Facebook\WebDriver\Exception\UnknownErrorException: unknown error: net::ERR_CONNECTION_REFUSED
(Session info: headless chrome=106.0.5249.119)
- APP_URL=http://localhost
+ APP_URL=http://localhost:8000
変更したらlaravelの.envに反映
こちらが参考になりました。
Laradockの再ビルド
docker-compose build --no-cache workspace
docker-compose up -d (ご使用のコンテナ)
Duskのインストール
LaraDockのworkspaceコンテナで下記を実行
composer require --dev laravel/dusk
php artisan dusk:install
コマンドは公式のドキュメントを参考にしました
vendor/laravel/dusk/bin/chromedriver-linux -v
↑公式ドキュメントにある、ChromedrDriverをインストールするコマンドは不要。
WORKSPACE_INSTALL_DUSK_DEPS=true
にしたことで、再ビルド時にインストールされている。
サンプルテストの実施
php artisan serve
// 別ターミナルで
php artisan dusk
ここで下記エラーが発生した場合は次の設定をする
1) Tests\Browser\ExampleTest::testBasicExample
Facebook\WebDriver\Exception\UnknownErrorException: unknown error: Chrome failed to start: crashed.
(unknown error: DevToolsActivePort file doesn't exist)
(The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
/var/www/vendor/php-webdriver/webdriver/lib/Exception/WebDriverException.php:143
/var/www/vendor/php-webdriver/webdriver/lib/Remote/HttpCommandExecutor.php:385
/var/www/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php:134
/var/www/tests/DuskTestCase.php:46
/var/www/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:219
/var/www/vendor/laravel/framework/src/Illuminate/Support/helpers.php:234
/var/www/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:220
/var/www/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:98
/var/www/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:66
/var/www/tests/Browser/ExampleTest.php:21
protected function driver()
{
$options = (new ChromeOptions)->addArguments(collect([
$this->shouldStartMaximized() ? '--start-maximized' : '--window-size=1920,1080',
])->unless($this->hasHeadlessDisabled(), function ($items) {
return $items->merge([
'--disable-gpu',
'--headless',
+ '--no-sandbox' // このコードを追加
]);
})->all());
return RemoteWebDriver::create(
$_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:9515',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY, $options
)
);
}
この状態で
php artisan dusk
を実行すると、下記のようにテストは通らない(Failuer)ものの、エラーは出ないはず
(テストが実行できる状態)
F 1 / 1 (100%)
Time: 00:04.673, Memory: 22.00 MB
There was 1 failure:
1) Tests\Browser\ExampleTest::testBasicExample
Did not see expected text [Laravel] within element [body].
Failed asserting that false is true.
/var/www/vendor/laravel/dusk/src/Concerns/MakesAssertions.php:181
/var/www/vendor/laravel/dusk/src/Concerns/MakesAssertions.php:152
/var/www/tests/Browser/ExampleTest.php:20
/var/www/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:69
/var/www/tests/Browser/ExampleTest.php:21
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
vue.js + laravelのテストを通す方法
ここで動かしたテストを見てみる
public function testBasicExample()
{
$this->browse(function (Browser $browser) {
$browser->visit('/')
->assertSee('Laravel');
});
}
vue.jsでつくられた/
(トップページ)には、メールアドレスという文字列があるので、
- ->assertSee('Laravel');
+ ->assertSee('メールアドレス');
とすれば、通りそうだが実際には通らない。
解決策はこちら↓
public function testBasicExample()
{
$this->browse(function (Browser $browser) {
$browser->visit('/')
+ ->waitFor('.index-component-root')
->assertSee('メールアドレス');
});
}
vue.jsを読み込んでいるので、それが終わってからassertしないと、無いことになってしまう。
なので、
->waitFor('.index-component-root')
で、文字列を含むDOM要素.index-component-root
が読み込まれるのを待ってから、
->assertSee('メールアドレス');
するようにする
この状態で
php artisan dusk
を実行すると、サンプルテストが通るようになる
. 1 / 1 (100%)
Time: 00:02.373, Memory: 22.00 MB
OK (1 test, 1 assertion)
今後これをもとにブラウザテストを実装していくことにする