首頁 >php框架 >Laravel >Laravel Dusk控制台的初學介紹(程式碼範例)

Laravel Dusk控制台的初學介紹(程式碼範例)

不言
不言轉載
2019-01-23 10:33:483892瀏覽

這篇文章帶給大家的內容是關於Laravel Dusk控制台的初學介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

Laravel Dusk 控制台是一款 Laravel 擴充包,能夠為你的 Dusk 測試套件提供漂亮的視覺面板。透過它,你可以視覺化執行 Dusk 測試時涉及的各個步驟,以及查看每個步驟的 DOM 快照。這對於調試瀏覽器測試、並搞清楚後台做了什麼十分有用。同時,你也可以使用瀏覽器的偵錯工具來檢查 DOM 快照。

Laravel Dusk控制台的初學介紹(程式碼範例)

#除了可視面板,此擴充包還提供了Laravel Dusk 測試監視器。在你對 Dusk 測試進行修改後,便會自動執行測試過程。

此擴充包受到 Javascript 前端測試框架 —— Cypress 的強烈啟發。

查看本擴充包,請移步 GitHub 。

什麼是 Laravel Dusk?

Laravel Dusk 提供了富有表現力的、易於使用的瀏覽器自動化和測試 API。使用 Laravel Dusk編寫測試案例,就像在真正的瀏覽器上一樣。例如,當你想在網站上測試拖放功能時,想要測試Vue元件或其他與 Javascript 相關功能,那麼你無法使用 Laravels HTTP 測試 API 本身進行測試。

我認為  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');
    });
}

要了解更多關於Laravel Dusk 以及如何開始使用自己的瀏覽器測試的更多信息,請查看 官方文件。

使用Laravel Dusk 控制台

在介紹Laravel Dusk 控制台內部如何運作之前,讓我們先瞥一眼如何在Laravel 應用程式內安裝並使用這個擴充包。

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

首先,使用 Composer 安裝本擴充包。

composer require --dev beyondcode/dusk-dashboard

接下來,開啟 Laravel Dusk 產生的 DuskTestCase.php。你可以在 tests 目錄裡找到這個檔案。

請務必使用本擴充包的測試案例(Test case)作為基底類,而不是 Laravel Dusk 的測試案例。稍後我再告訴你內部原理。

找到此行:

use Laravel\Dusk\TestCase as BaseTestCase;

使用以下內容替換:

use BeyondCode\DuskDashboard\Testing\TestCase as BaseTestCase;

搞定。

現在你可以使用以下指令啟動 Laravel Dusk 控制台,並執行你的測試了。

php artisan dusk:dashboard

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

Laravel Dusk控制台的初學介紹(程式碼範例)

開始測試

只需按下「Start Tests」按鈕,即可執行Laravel Dusk 測試,並觀察到你的應用被測試時的輸出,以及所發生的行為。

隨後,你便會看到 Dusk 測驗產生的各種事件出現在你的控制台上。

Laravel Dusk控制台的初學介紹(程式碼範例)

還有一種啟動 Dusk 測試的方法是,只要編輯任一測試檔案然後儲存即可。 Laravel Dusk 控制台內建了檔案監視器。

調試測試步驟

你可以點擊展示在清單中的測試行為,來調試和檢查它們。點擊後,你將會看到 DOM 快照,表示當此行為被記錄時的 HTML 頁面狀態。若此行為以某種方式操作過 DOM,那麼你也可以點擊 “Before”和“After”按鈕在事件發生“之前”或“之後”的 DOM 快照之間進行切換。

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

Laravel Dusk控制台的初學介紹(程式碼範例)

#檢查XHR請求

有時候,查看執行測試時發生的有關XHR 請求的其他資訊可能會很有用。例如:你網站上又一個按鈕,它將對某個服務端執行 GET 請求。

Dusk Dashboard 可讓您記錄 XHR 事件,並顯示回應狀態和回應路徑。

Laravel Dusk控制台的初學介紹(程式碼範例)

預設情況下 XHR 請求檢查不會啟用,因為它需要你修改瀏覽器功能。

要启用 XHR 的请求记录,打开你的  DuskTestCase.php ,在文件里,有个 driver 方法,用于设置不同测试操作的 WebDriver。由于此程序包需要对此驱动程序的功能进行一些调整,因此需要使用 $this->enableNetworkLogging 方法调用来封装  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 请求和响应信息所需的功能。

工作原理

基本思路十分简单:运行一个 WebSocket 服务,控制台用户连接到这个 WebSocket 服务,接着 PHPUnit 便会将浏览器事件和失败信息发送至所有 WebSocket 连接。

以下是具体的实现方式:

在内部,此扩展包向你的 Laravel 应用内添加了一个名为 StartDashboardCommand 的命令。当此命令被执行时,就会 启动 一个由 Ratchet 开发的 WebSocket 服务。最初我考虑基于我同 Freek 一起开发的 Laravel Websockets 实现此功能,然而随后就毙了这个想法。原因很简单,此扩展包仅能用作开发依赖项,并且我不需要 Pusher 或 Laravel 广播功能,因为广播是通过 PHPUnit 内部实现的。

译者注:Freek 意指 Freek Van der Herten。
另,截至目前,此扩展包也已经发布 v1.0.x 稳定版本。

接下来,我添加两条路由到 WebSocket 服务。

$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 数据,并广播给所有已连接的 WebSocket 客户端:

class EventController extends Controller
{
    public function onOpen(ConnectionInterface $conn, RequestInterface $request = null)
    {
        try {
            /*
             * 如下即为从 PHPUnit 测试发来的 POST 数据,
             * 发送到已连接的客户端。
             */
            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();
    }
}

收集浏览器行为

这是整个扩展包最乏味的部分。因为若想收集所有 Laravel Dusk 方法,并将它们广播到 WebSocket 连接,那么必须代理所有的消息再收集它们。

在本扩展包自定义的 TestCase 类里,我们能够重写(override)浏览器实例被创建的过程。那么,此处就是我注入自定义的浏览器(Browser)类的地方。它负责代理现有方法并收集所有行为,同时转发给 WebSocket 连接。

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

没什么高端操作。接下来,我原本想直接创建一个新类,传给它 Laravel Dusk 的浏览器类,随后使用 __call 魔术方法代理所有的方法。这能够省下一大堆代码,但也会引出两个问题:

用户无法使用 IDE 自动完成、方法提示功能。

对我来说有点忍不了,我认为这是个非常重要的特性 —— 尤其是对于测试工具来说。开发者并不了解 API 的输入和输出,因此需要 IDE 的提示。

另一个问题是,我不仅仅想在浏览器行为发生后记录 DOM 快照,在某些特定的行为发生前,同样想记录快照。

所以这就是我为何不得不像下面这样,代理所有 Laravel Dusk 方法:

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

    return parent::assertTitle($title);
}

好了,这样我便能收集并记录各个行为,且依然维持着 IDE 自动完成功能。棒棒哒!

现在你能看到这里的 actionCollector 是 PHPUnit 和 WebSocket 客户端之间的桥梁。它收集获得的信息,并用例如测试名称和 WebSocket POST 推送的端点数据来丰富它:

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 服务器可能是关闭的。不必惊慌。
    }
}

它由 try-catch 包裹来保证即使在 Dusk Dashboard 服务器关闭时 Laravel Dusk 也能正常运行。

UI 界面

最后,值得注意的是,此扩展包在它的面板界面里也有很多说道。它由 TailwindCSS 和 Vue 驱动来展示到来的事件以及过滤它们等等。你可以在这 这 查看起始页面的代码。

差不多就这些了。

以上是Laravel Dusk控制台的初學介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除