今天要來說說在 Laravel 中寫 UI 的測試。
我們目前已經有了登入、註冊、貼文的頁面,但是當時沒有遵循 TDD,現在補上應該還不算太晚!
5b
。從 Larevel 5.4 開始,UI 的測試功能被獨立到 laravel/dusk 套件中,我們先來安裝。
$ composer require --dev laravel/dusk
接著需要 Dusk 幫我們建置幾個基本的檔案,Dusk 的測試會被放在 tests/Browsers
中:
$ php artisan dusk:install
此時就已經包含了一個 Dusk 的範例測試在裡面,所有 Dusk 的測試都是繼承自 DuskTestCase
類別。
Dusk 跟 PHPUnit 其實是獨立分開的測試套件,因此並不會抓取 phpunit.xml
中的測試環境設定。
因此我們新增一個專用的設定檔 .env.dusk.local
,Dusk 會自動在執行測試時,暫時將 .env
環境設定用 .env.dusk.local
取代掉。
其中兩個設定需要更改:APP_URL
與 DB_CONNECTION
。
APP_URL
看我們的伺服器在哪裡執行,Dusk 需要在伺服器運作中的狀態才能執行,並透過 APP_URL
的網址做測試。
我是用 Valet
協助進行開發,因此是資料夾名稱+test [1]。
DB 則要使用新的資料庫設定。
APP_URL=http://tdd_for_article.test
DB_CONNECTION=sqlite_testing
為了讓 Dusk 測試用的資料庫獨立出來,新增一個資料庫 sqlite_testing
的設定,避免不小心把原本的資料庫清空。
// config/database.php
'connections' => [
// 原本的
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
// 新增的設定
'sqlite_testing' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => database_path('dusk.sqlite'),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
更改之後,在 database/
資料夾中新增一個 dusk.sqlite
檔案。
透過這個指令來執行 Dusk 的測試。
$ php artisan dusk
範例測試中,尋找的字樣是 Laravel
,改成 TDD_Blog
就能看到通過的測試。
Dusk 預設是使用 Chrome 來做測試,也可以使用其他的瀏覽器。
讓我們實際來編寫目前頁面的測試吧!透過指令來協助產生程式碼:
$ php artisan dusk:make LoginTest
修改一下,改成登入的測試。
這邊會先在資料庫新增一筆假的使用者資料,並在登入頁面中輸入資料登入。
<?php
// tests/Browser/LoginTest.php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use App\User;
class LoginTest extends DuskTestCase
{
use DatabaseMigrations;
public function testLogin()
{
$user = factory(User::class)->create([
'email' => 'taylor@laravel.com',
]);
$this->browse(function ($browser) use ($user) {
$browser->visit('/login')
->type('email', $user->email)
->type('password', 'password')
->press('Login')
->assertPathIs('/home');
});
}
}
同樣註冊的頁面也來寫測試。
<?php
// tests/Browser/RegisterTest.php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use App\User;
class RegisterTest extends DuskTestCase
{
use DatabaseMigrations;
protected function setUp(): void
{
parent::setUp();
$this->withoutExceptionHandling();
}
public function testLogin()
{
$this->browse(function ($browser) {
$browser->visit('/register')
->type('name', 'Louis')
->type('email', 'l@com')
->type('password', 'myPassword')
->type('password_confirmation', 'myPassword')
->press('Register');
});
$this->assertDatabaseHas('users', [
'name' => 'Louis',
'email' => 'l@com'
]);
}
}
( $ git checkout 5b
)
使用 $ php artisan dusk
來執行測試,由於 UI 的測試執行要透過瀏覽器,因此會比我們之前寫過的測試都還要慢。
$ php artisan dusk
PHPUnit 8.3.5 by Sebastian Bergmann and contributors.
.. 2 / 2 (100%)
Time: 4.08 seconds, Memory: 26.00 MB
OK (2 tests, 2 assertions)
學會了 UI 的測試,之後新的頁面也能夠用 TDD 來開發了!
附註