iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 22
0
Software Development

如何一步步實踐TDD (測試驅動開發)系列 第 22

TDD 實戰 D8:Laravel UI 測試 (Dusk)

今天要來說說在 Laravel 中寫 UI 的測試。

我們目前已經有了登入、註冊、貼文的頁面,但是當時沒有遵循 TDD,現在補上應該還不算太晚!

  • 關於 如何使用範例程式碼,請參考 TDD 實戰 D1
    • 本篇版本包含:5b

Laravel Dusk

從 Larevel 5.4 開始,UI 的測試功能被獨立到 laravel/dusk 套件中,我們先來安裝。

$ composer require --dev laravel/dusk

接著需要 Dusk 幫我們建置幾個基本的檔案,Dusk 的測試會被放在 tests/Browsers 中:

$ php artisan dusk:install

此時就已經包含了一個 Dusk 的範例測試在裡面,所有 Dusk 的測試都是繼承自 DuskTestCase 類別。

.env.dusk.local

Dusk 跟 PHPUnit 其實是獨立分開的測試套件,因此並不會抓取 phpunit.xml 中的測試環境設定。

因此我們新增一個專用的設定檔 .env.dusk.local,Dusk 會自動在執行測試時,暫時將 .env 環境設定用 .env.dusk.local 取代掉。

其中兩個設定需要更改:APP_URLDB_CONNECTION

APP_URL 看我們的伺服器在哪裡執行,Dusk 需要在伺服器運作中的狀態才能執行,並透過 APP_URL 的網址做測試。

我是用 Valet 協助進行開發,因此是資料夾名稱+test [1]。

DB 則要使用新的資料庫設定。

APP_URL=http://tdd_for_article.test
DB_CONNECTION=sqlite_testing

Database 設定

為了讓 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 測試!

透過這個指令來執行 Dusk 的測試。

$ php artisan dusk

範例測試中,尋找的字樣是 Laravel,改成 TDD_Blog 就能看到通過的測試。

Dusk 預設是使用 Chrome 來做測試,也可以使用其他的瀏覽器。

LoginTest

讓我們實際來編寫目前頁面的測試吧!透過指令來協助產生程式碼:

$ 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');
        });
    }
}

RegisterTest

同樣註冊的頁面也來寫測試。

<?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 來開發了!


附註

  1. 本篇文章中未介紹 Valet 的使用,可參考 Laravel Valet - Installation

上一篇
TDD 實戰 D7:Laravel 會員登入與註冊
下一篇
TDD 實戰 D9:Laravel 關聯式資料庫
系列文
如何一步步實踐TDD (測試驅動開發)30

尚未有邦友留言

立即登入留言