Browser testing with laravel dusk
Mở đầu Khi bạn viết end-to-end tests, Laravel cung cấp một tập hợp các phương thức hữu ích giúp bạn dễ dàng nhấp vào một liên kết, điền form, hay submit một form...Laravel sử dụng thành phần Symfony BrowserKit để mô phỏng hoạt động của trình duyệt web. Tuy nhiên, nếu ứng dụng của bạn sử dụng ...
Mở đầu
Khi bạn viết end-to-end tests, Laravel cung cấp một tập hợp các phương thức hữu ích giúp bạn dễ dàng nhấp vào một liên kết, điền form, hay submit một form...Laravel sử dụng thành phần Symfony BrowserKit để mô phỏng hoạt động của trình duyệt web. Tuy nhiên, nếu ứng dụng của bạn sử dụng Javascript và AJAX để load trang thì BrowserKit sẽ bó tay. Và Dusk sẽ giải quyết vấn đề trên, nhằm giả lập các thao tác như click, điền form, thậm chí là kéo và thả trong các ứng dụng dùng Javascript. Có được điều này là do Dusk sử dụng ChromeDriver và Facebook Php-webdriver. Khi bạn viết application tests, Dusk gửi các lệnh của bạn tới ChromeDriver, sau đó trên Chorme chạy các tests của bạn trên trình duyệt và báo cáo lại kết quả (tự động chụp và lưu screenshot ứng dụng khi chạy test bị fail).
Cài đặt
Cài đặt Laravel Dusk bằng composer như sau: composer require laravel/dusk Tiếp theo, chúng ta cần đăng ký DuskServiceProvider trong ứng dụng. Có thể làm bằng 2 cách như sau:
- Cách 1: Include trong providers array trong file config/app.php : LaravelDuskDuskServiceProvider::class, Với cách này, DuskServiceProvider sẽ được đăng ký trong ứng dụng cho tất cả các môi trường.
- Cách 2: Đăng ký DuskServiceProvider trong AppServiceProvider class cho các môi trường cụ thể:
public function register() { if ($this->app->environment('local', 'testing', 'staging')) { $this->app->register(DuskServiceProvider::class); } }
Cuối cùng, hoàn tất quá trình cài đặt: php artisan dusk:install Chú ý: thêm APP_URL của bạn vào file .env Khi đó, một file Browser được tạo ra trong thư mục tests trong ứng dụng của bạn.
Our First Test
Tạo một Dusk test đầu tiên php artisan dusk:make LoginTest Lệnh trên sẽ tạo một LoginTst class trong thư mục Browser.
class LoginTest extends DuskTestCase { /** * A Dusk test example. * * @return void */ public function test_I_can_login_successfully() { $this->browse(function ($browser) { $browser->visit('/login') ->type('email', 'viraj@virajkhatavkar.com') ->type('password', 'secret') ->press('Login') ->assertSee('You are logged in!'); }); } }
Test case ở trên, cho phép chúng ta kiểm tra xem người dùng có thể đăng nhập thành công vào hệ thống hay không và xem trên trang home với thông điệp 'You are logged in!' Chú ý: Để kiểm tra thành công chúng ta cần một người dùng thực trong cơ sở dữ liệu với thông tin tài khoản như trên. Chạy lệnh sau để thực hiện test: php artisan dusk Nếu trong database của bạn tồn tại một tài khoản như trên, khi đó kết quả như sau:
PHPUnit 5.7.6 by Sebastian Bergmann and contributors. .. 2 / 2 (100%) Time: 4.71 seconds, Memory: 10.00MB OK (2 tests, 2 assertions)
Failed Tests
Giả sử, đăng nhập bằng tài khoản không tồn tại trong hệ thống
public function test_I_can_login_successfully() { $this->browse(function ($browser) { $browser->visit('/login') ->type('email', 'viraj123@gmail.com') ->type('password', 'secret') ->press('Login') ->assertSee('You are logged in!'); }); }
Khi chạy Dusk test kết quả sẽ như sau: Khi test lỗi, thì Dusk sẽ chụp màn hình của trang và lưu trong thư mực screenshots. Điểu này, cho chúng ta thấy một biểu hiện trực quan lý do tại sao thử nghiệm của chúng ta không thành công và giúp cho chúng ta có thể xác định nhanh chóng vấn đề.
Testing AJAX Calls
Ví dụ demo: Chúng ta sử dụng AJAX đêt tạo một task mới, sau đó điều hướng người dùng tới trang danh sách các task. php artisan dusk:make CreateTaskTest Lênh trên sẽ tạo ra một CreateTaskTest class trong thư mục Browser, và viết test như sau:
public function test_I_can_create_task_successfully() { $this->browse(function ($browser) { $browser->visit('/tasks/create') ->type('title', 'My Task') ->press('Add Task') ->pause(5000) ->assertPathIs('/tasks'); }); }
Sau đó hãy chạy Dusk test và xem kết quả: Như bạn thấy, testcase đã thành công. Ngoài ra, chúng ta cũng có thể sử dụng waitUntilMissing API của Dusk để test
public function test_I_can_create_task_successfully() { $this->browse(function ($browser) { $browser->visit('/tasks/create') ->type('title', 'My Task') ->press('Add Task') ->waitUntilMissing('.btn-primary') ->assertPathIs('/tasks'); }); }
Bạn có thể tham khảo tài liệu để tìm hiểu về các yếu tố chờ đợi khác có sẵn trong API.
Pages
Chúng ta sử dụng Pages để tạo lại CreateTaskPage như sau: php artisan dusk:page CreateTaskPage Lênh trên sẽ tạo một CreateTaskPage trong thư mục Pages.
public function url() { return '/tasks/create'; }
Bất cứ khi nào trang này được gọi, Dusk sẽ điều hướng đến url này.
public function assert(Browser $browser) { $browser->assertPathIs($this->url()); }
Trong ví dụ trên, tôi chỉ đơn giản khẳng định rằng url của trang đang hoạt động là thích hợp.
public function elements() { return [ '@addTask' => '.btn-primary', ]; }
Các elements method có thể có bộ chọn sẵn được xác định trước. Chúng ta có thể xác định tên người dùng có thể đọc được cho bộ chọn và sử dụng lại chúng cho trang này trong các trường hợp thử nghiệm khác nhau. Trong ví dụ trên, tôi đã xác định một nút chọn cho nút addTask Bây giờ chúng ta hãy sửa đổi CreateTaskTest class và sử dụng bộ chọn:
public function test_I_can_create_task_successfully() { $this->browse(function ($browser) { $user = factory(User::class)->create(); $browser->loginAs($user) ->visit(new CreateTaskPage) ->type('title', 'My Task') ->click('@addTask') ->waitUntilMissing('@addTask') ->assertPathIs('/tasks'); }); }
Giờ thì chỉ cần chạy Dusk test và kết quả như sau:
PHPUnit 5.7.13 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 2.76 seconds, Memory: 12.00MB OK (1 test, 2 assertions)
Bạn thậm chí có thể xác định các phương pháp tùy chỉnh để thực hiện một số hành động tái sử dụng trên một trang nhất định. Bạn có thể đọc thêm về nó trong tài liệu
Kết Luận
Trong bài viết này, tôi đã giới thiệu về Laravel Dusk, cách cài đặt và hướng dẫn test một số chức năng cơ bản. Sau khi tìm hiểu phần này mình thấy nó thực sự rất hay và để hiểu về nó, hãy thử thực nghiệm nhé