Laravel Dusk控制臺的初學(xué)介紹(代碼示例)

本篇文章給大家?guī)淼膬?nèi)容是關(guān)于laravel dusk控制臺的初學(xué)介紹(代碼示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

laravel Dusk 控制臺是一款 Laravel 擴(kuò)展包,能夠為你的 Dusk 測試套件提供漂亮的可視面板。通過它,你可以可視化運行 Dusk 測試時涉及的各個步驟,以及查看每個步驟的 DOM 快照。這對于調(diào)試瀏覽器測試、并搞清楚后臺做了什么十分有用。同時,你還可以使用瀏覽器的調(diào)試工具來檢查 DOM 快照。

Laravel Dusk控制臺的初學(xué)介紹(代碼示例)

除了可視面板,此擴(kuò)展包還提供了 Laravel Dusk 測試監(jiān)視器。在你對 Dusk 測試進(jìn)行修改后,便會自動執(zhí)行測試過程。

該擴(kuò)展包受到 Javascript 前端測試框架 —— Cypress 的強(qiáng)烈啟發(fā)。

查看本擴(kuò)展包,請移步 GitHub 。

什么是 Laravel Dusk?

Laravel Dusk 提供了富有表現(xiàn)力的、易于使用的瀏覽器自動化和測試 API。使用 Laravel Dusk編寫測試用例,像在真正的瀏覽器上一樣。比如,當(dāng)你想在網(wǎng)站上測試拖放功能時,想要測試Vue組件或其他與 Javascript 相關(guān)功能,那么你無法使用 Laravels HTTP 測試 API 本身進(jìn)行測試。

我認(rèn)為 ?Laravel Dusk 是一個非常棒的軟件包并且可以簡化瀏覽器測試。
以下是一個用戶注冊的示例測試,以便你可以了解 ?Laravel Dusk 的功能:

public function test_can_register() {     $faker = Factory::create();      $this->browse(function($browser) use ($faker) {         $password = $faker->password(9);          $browser->visit('/register')             ->assertSee('Register')             ->type('name', $faker->name)             ->type('email', $faker->safeEmail)             ->type('password', $password)             ->type('password_confirmation', $password)             ->press('Register')             ->assertPathIs('/home');     }); }

要了解更多關(guān)于 Laravel Dusk 以及如何開始使用自己的瀏覽器測試的更多信息,請查看?官方文檔。

使用 Laravel Dusk 控制臺

在介紹 Laravel Dusk 控制臺內(nèi)部如何運行之前,讓我們先瞄一眼如何在 Laravel 應(yīng)用內(nèi)安裝并使用這個擴(kuò)展包。

如下步驟假定你已經(jīng)按照?官方文檔?成功地安裝了 Laravel Dusk;或者甚至你已經(jīng)寫好了一些 Dusk 測試。

首先,使用 Composer 安裝本擴(kuò)展包。

composer require --dev beyondcode/dusk-dashboard

接下來,打開 Laravel Dusk 生成的 DuskTestCase.php。你可以在 tests 目錄里找到這個文件。

請務(wù)必使用本擴(kuò)展包的測試用例(Test case)作為基類,而不是 Laravel Dusk 的測試用例。稍后我再告訴你內(nèi)部原理。

找到此行:

use LaravelDuskTestCase as BaseTestCase;

使用如下內(nèi)容替換:

use BeyondCodeDuskDashboardTestingTestCase as BaseTestCase;

搞定。

現(xiàn)在你可以使用如下命令啟動 Laravel Dusk 控制臺,并執(zhí)行你的測試了。

php artisan dusk:dashboard

類似這樣的界面便會展示在你的面前:

Laravel Dusk控制臺的初學(xué)介紹(代碼示例)

開始測試

只需按下「Start Tests」按鈕,即可運行 Laravel Dusk 測試,并觀察到你的應(yīng)用被測試時的輸出,以及所發(fā)生的行為。

隨后,你便會看到 Dusk 測試產(chǎn)生的各種事件出現(xiàn)在你的控制臺上。

Laravel Dusk控制臺的初學(xué)介紹(代碼示例)

還有一種啟動 Dusk 測試的方法是,只要編輯任意一個測試文件然后保存即可。Laravel Dusk 控制臺內(nèi)置了文件監(jiān)視器。

調(diào)試測試步驟

你可以通過點擊展示在列表中的測試行為,來調(diào)試和檢查它們。點擊后,你將會看到 DOM 快照,表示當(dāng)此行為被記錄時的 HTML 頁面狀態(tài)。若此行為以某種方式操作過 DOM,那么你也可以點擊 「Before」和「After」按鈕在事件發(fā)生「之前」或「之后」的 DOM 快照之間進(jìn)行切換。

如下,一個按下「Register」按鈕的小例子:

Laravel Dusk控制臺的初學(xué)介紹(代碼示例)

檢查XHR請求

有時候,查看運行測試時發(fā)生的有關(guān) XHR 請求的其他信息可能會很有用。例如:你網(wǎng)站上又一個按鈕,它將對某個服務(wù)端執(zhí)行 GET 請求。

Dusk Dashboard 允許您記錄 XHR 事件,并顯示響應(yīng)狀態(tài)和響應(yīng)路徑。

Laravel Dusk控制臺的初學(xué)介紹(代碼示例)

默認(rèn)情況下 XHR 請求檢查不會啟用,因為它需要你修改瀏覽器功能。

要啟用 XHR 的請求記錄,打開你的 ?DuskTestCase.php ,在文件里,有個?driver 方法,用于設(shè)置不同測試操作的 WebDriver。由于此程序包需要對此驅(qū)動程序的功能進(jìn)行一些調(diào)整,因此需要使用 $this->enableNetworkLogging 方法調(diào)用來封裝 ?DesiredCapabilities 對象。

protected function driver() {     $options = (new ChromeOptions)->addArguments([         '--disable-gpu',         '--headless',         '--window-size=1920,1080',     ]);      return RemoteWebDriver::create(         'http://localhost:9515', $this->enableNetworkLogging(             DesiredCapabilities::chrome()->setCapability(             ChromeOptions::CAPABILITY, $options             )         )     ); }

通過添加此功能,該程序包將啟用記錄 XHR 請求和響應(yīng)信息所需的功能。

工作原理

基本思路十分簡單:運行一個 WebSocket 服務(wù),控制臺用戶連接到這個 WebSocket 服務(wù),接著 PHPUnit 便會將瀏覽器事件和失敗信息發(fā)送至所有 WebSocket 連接。

以下是具體的實現(xiàn)方式:

在內(nèi)部,此擴(kuò)展包向你的 Laravel 應(yīng)用內(nèi)添加了一個名為 StartDashboardCommand 的命令。當(dāng)此命令被執(zhí)行時,就會 啟動 一個由 Ratchet 開發(fā)的 WebSocket 服務(wù)。最初我考慮基于我同 Freek 一起開發(fā)的 Laravel Websockets 實現(xiàn)此功能,然而隨后就斃了這個想法。原因很簡單,此擴(kuò)展包僅能用作開發(fā)依賴項,并且我不需要 Pusher 或 Laravel 廣播功能,因為廣播是通過 PHPUnit 內(nèi)部實現(xiàn)的。

譯者注:Freek 意指 Freek Van der Herten。另,截至目前,此擴(kuò)展包也已經(jīng)發(fā)布 v1.0.x 穩(wěn)定版本。

接下來,我添加兩條路由到 WebSocket 服務(wù)。

$dashboardRoute = new Route('/dashboard', ['_controller' => new DashboardController()], [], [], null, [], ['GET']);  $this->app->routes->add('dashboard', $dashboardRoute);  $eventRoute = new Route('/events', ['_controller' => new EventController()], [], [], null, [], ['POST']);  $this->app->routes->add('events', $eventRoute);

$dashboardRoute 是一條普通 HTTP 控制器路由,用于輸出 Laravel Dusk 控制臺的 HTML 視圖。

就是這么簡單,它只做一件事——返回 HTML 視圖:

class DashboardController extends Controller {     public function onOpen(ConnectionInterface $connection, RequestInterface $request = null)     {         $connection->send(             str(new Response(                 200,                 ['Content-Type' => 'text/html'],                 file_get_contents(__DIR__.'/../../../resources/views/index.html')             ))         );         $connection->close();     } }

$eventRoute?同樣是一個 HTTP 路由,但只允許 POST 請求。它被用來在 PHPUnit 和 WebSocket 客戶端之間通訊。

同樣十分簡單,也只做一件事——接收 POST 數(shù)據(jù),并廣播給所有已連接的 WebSocket 客戶端:

class EventController extends Controller {     public function onOpen(ConnectionInterface $conn, RequestInterface $request = null)     {         try {             /*              * 如下即為從 PHPUnit 測試發(fā)來的 POST 數(shù)據(jù),              * 發(fā)送到已連接的客戶端。              */             foreach (Socket::$connections as $connection) {                 $connection->send($request->getBody());             }             $conn->send(str(new Response(200)));         } catch (Exception $e) {             $conn->send(str(new Response(500, [], $e->getMessage())));         }         $conn->close();     } }

收集瀏覽器行為

這是整個擴(kuò)展包最乏味的部分。因為若想收集所有 Laravel Dusk 方法,并將它們廣播到 WebSocket 連接,那么必須代理所有的消息再收集它們。

在本擴(kuò)展包自定義的 TestCase 類里,我們能夠重寫(override)瀏覽器實例被創(chuàng)建的過程。那么,此處就是我注入自定義的瀏覽器(Browser)類的地方。它負(fù)責(zé)代理現(xiàn)有方法并收集所有行為,同時轉(zhuǎn)發(fā)給 WebSocket 連接。

protected function newBrowser($driver) {     return new Browser($driver); }

沒什么高端操作。接下來,我原本想直接創(chuàng)建一個新類,傳給它 Laravel Dusk 的瀏覽器類,隨后使用 __call 魔術(shù)方法代理所有的方法。這能夠省下一大堆代碼,但也會引出兩個問題:

用戶無法使用 IDE 自動完成、方法提示功能。

對我來說有點忍不了,我認(rèn)為這是個非常重要的特性 —— 尤其是對于測試工具來說。開發(fā)者并不了解 API 的輸入和輸出,因此需要 IDE 的提示。

另一個問題是,我不僅僅想在瀏覽器行為發(fā)生后記錄 DOM 快照,在某些特定的行為發(fā)生前,同樣想記錄快照。

所以這就是我為何不得不像下面這樣,代理所有 Laravel Dusk 方法:

/** @inheritdoc */ public function assertTitle($title) {     $this->actionCollector->collect(__FUNCTION__, func_get_args(), $this);      return parent::assertTitle($title); }

好了,這樣我便能收集并記錄各個行為,且依然維持著 IDE 自動完成功能。棒棒噠!

現(xiàn)在你能看到這里的?actionCollector?是 PHPUnit 和 WebSocket 客戶端之間的橋梁。它收集獲得的信息,并用例如測試名稱和 WebSocket POST 推送的端點數(shù)據(jù)來豐富它:

protected function pushAction(string $name, array $payload) {     try {         $this->client->post('http://127.0.0.1:'.StartDashboardCommand::PORT.'/events', [             RequestOptions::JSON => [                 'channel' => 'dusk-dashboard',                 'name' => $name,                 'data' => $payload,             ],         ]);     } catch (Exception $e) {         // Dusk-Dashboard 服務(wù)器可能是關(guān)閉的。不必驚慌。     } }

它由 try-catch 包裹來保證即使在 Dusk Dashboard 服務(wù)器關(guān)閉時 Laravel Dusk 也能正常運行。

UI 界面

最后,值得注意的是,此擴(kuò)展包在它的面板界面里也有很多說道。它由 TailwindCSS 和 Vue 驅(qū)動來展示到來的事件以及過濾它們等等。你可以在這?這 查看起始頁面的代碼。

差不多就這些了。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊12 分享