eliurkis/laravel-browser-kit-testing

为最新版的 Laravel 提供对 BrowserKit 测试的向下兼容性。

v5.1.3 2019-03-11 02:43 UTC

README

Build Status Total Downloads Latest Stable Version License

此包为最新 Laravel 版本中 Laravel 5.3 风格的 "BrowserKit" 测试提供向后兼容层。

官方文档

安装

首先,安装此包

composer require laravel/browser-kit-testing --dev

然后,修改您的应用程序的基础 TestCase 类,使其扩展 Laravel\BrowserKitTesting\TestCase 而不是 Illuminate\Foundation\Testing\TestCase

<?php

namespace Tests;

use Laravel\BrowserKitTesting\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;

    public $baseUrl = 'https://';

    // ...
}

您的测试不需要其他修改。

介绍

Laravel BrowserKit 测试提供了一种非常流畅的 API,用于向应用程序发送 HTTP 请求、检查输出,甚至填写表单。例如,看看下面的测试定义

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->visit('/')
             ->see('Laravel')
             ->dontSee('Rails');
    }
}

visit 方法向应用程序发送一个 GET 请求。 see 方法断言我们应在应用程序返回的响应中看到给定的文本。 dontSee 方法断言给定的文本没有出现在应用程序的响应中。这是 Laravel 中最基本的应用程序测试。

您还可以使用 'visitRoute' 方法通过命名路由发送一个 'GET' 请求

$this->visitRoute('profile');

$this->visitRoute('profile', ['user' => 1]);

与应用程序交互

当然,您可以做的不仅仅是在给定的响应中断言文本出现。让我们看看点击链接和填写表单的一些示例

与链接交互

在这个测试中,我们将向应用程序发送请求,"点击" 返回响应中的链接,然后断言我们到达了给定的 URI。例如,假设我们的响应中有一个文本值为 "关于我们" 的链接

<a href="/about-us">About Us</a>

现在,让我们编写一个测试,点击该链接并断言用户到达了正确的页面

public function testBasicExample()
{
    $this->visit('/')
         ->click('About Us')
         ->seePageIs('/about-us');
}

您还可以使用 seeRouteIs 方法检查用户是否到达了正确的命名路由

->seeRouteIs('profile', ['user' => 1]);

与表单交互

Laravel 还提供了一些用于测试表单的方法。 typeselectcheckattachpress 方法允许您与表单的所有输入进行交互。例如,让我们想象这个表单存在于应用程序的注册页面上

<form action="/register" method="POST">
    {{ csrf_field() }}

    <div>
        Name: <input type="text" name="name">
    </div>

    <div>
        <input type="checkbox" value="yes" name="terms"> Accept Terms
    </div>

    <div>
        <input type="submit" value="Register">
    </div>
</form>

我们可以编写一个测试来填写这个表单并检查结果

public function testNewUserRegistration()
{
    $this->visit('/register')
         ->type('Taylor', 'name')
         ->check('terms')
         ->press('Register')
         ->seePageIs('/dashboard');
}

当然,如果您的表单包含其他输入,如单选按钮或下拉框,您也可以轻松地填写这些类型的字段。以下是每个表单操作方法的列表

文件输入

如果您的表单包含 file 输入,您可以使用 attach 方法将文件附加到表单上

public function testPhotoCanBeUploaded()
{
    $this->visit('/upload')
         ->attach($pathToFile, 'photo')
         ->press('Upload')
         ->see('Upload Successful!');
}

测试 JSON API

Laravel 还提供了一些用于测试 JSON API 及其响应的辅助工具。例如,jsongetpostputpatchdelete 方法可以用于使用不同的 HTTP 动词发送请求。您还可以轻松地将数据和头传递给这些方法。为了开始,让我们编写一个测试,向 /user 发送一个 POST 请求并断言返回了预期的数据

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->json('POST', '/user', ['name' => 'Sally'])
             ->seeJson([
                 'created' => true,
             ]);
    }
}

{提示} seeJson 方法将给定的数组转换为 JSON,然后验证给定的 JSON 片段是否出现在应用程序返回的整个 JSON 响应中的任何地方。因此,如果 JSON 响应中还有其他属性,只要给定的片段存在,此测试仍然会通过。

验证精确匹配

如果您想验证给定的数组是否与应用程序返回的JSON完全匹配,您应使用seeJsonEquals方法。

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->json('POST', '/user', ['name' => 'Sally'])
             ->seeJsonEquals([
                 'created' => true,
             ]);
    }
}

验证结构匹配

也可以验证JSON响应是否符合特定的结构。在这种情况下,您应使用seeJsonStructure方法,并将您期望的JSON结构传递给它。

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->get('/user/1')
             ->seeJsonStructure([
                 'name',
                 'pet' => [
                     'name',
                     'age',
                 ],
             ]);
    }
}

上述示例说明了期望接收一个name属性和一个嵌套的包含自己的nameage属性的pet对象。如果响应中存在额外的键,seeJsonStructure也不会失败。例如,如果petweight属性,测试仍然会通过。

您可以使用*来断言返回的JSON结构中有一个列表,其中每个列表项都包含在值集中找到的属性。

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        // Assert that each user in the list has at least an id, name and email attribute.
        $this->get('/users')
             ->seeJsonStructure([
                 '*' => [
                     'id',
                     'name',
                     'email',
                 ],
             ]);
    }
}

您还可以嵌套使用*表示法。在这种情况下,我们将断言JSON响应中的每个用户都包含一组指定的属性,并且每个用户上的每只宠物也包含一组指定的属性。

$this->get('/users')
     ->seeJsonStructure([
         '*' => [
             'id', 'name', 'email', 'pets' => [
                 '*' => [
                     'name',
                     'age',
                 ],
             ],
         ],
     ]);

会话/认证

Laravel为测试期间使用会话提供了几个辅助函数。首先,您可以使用withSession方法将会话数据设置为给定的数组。这在在向您的应用程序发出请求之前加载数据到会话中非常有用。

<?php

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $this->withSession(['foo' => 'bar'])
             ->visit('/');
    }
}

当然,会话的一个常见用途是维护已认证用户的会话状态。actingAs辅助方法提供了一种简单的方式来认证指定的用户为当前用户。例如,我们可以使用模型工厂来生成和认证用户。

<?php

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $user = factory(App\User::class)->create();

        $this->actingAs($user)
             ->withSession(['foo' => 'bar'])
             ->visit('/')
             ->see('Hello, '.$user->name);
    }
}

您还可以通过将守卫名称作为actingAs方法的第二个参数传递来指定应使用哪个守卫来认证指定的用户。

$this->actingAs($user, 'api')

禁用中间件

在测试您的应用程序时,您可能会发现禁用中间件对某些测试很有用。这将允许您在隔离中间件关注点的情况下测试您的路由和控制器。Laravel包括一个简单的WithoutMiddleware特质,您可以使用它来自动禁用测试类的所有中间件。

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    use WithoutMiddleware;

    //
}

如果您只想禁用少数测试方法的中间件,您可以从测试方法中调用withoutMiddleware方法。

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->withoutMiddleware();

        $this->visit('/')
             ->see('Laravel');
    }
}

自定义 HTTP 请求

如果您想向您的应用程序发送自定义HTTP请求并获取完整的Illuminate\Http\Response对象,您可以使用call方法。

public function testApplication()
{
    $response = $this->call('GET', '/');

    $this->assertEquals(200, $response->status());
}

如果您正在发送POSTPUTPATCH请求,您可以将输入数据数组传递给请求。当然,这些数据将通过请求实例在您的路由和控制器中可用。

$response = $this->call('POST', '/user', ['name' => 'Taylor']);

PHPUnit 断言

Laravel为PHPUnit测试提供了一系列自定义断言方法。

许可协议

Laravel BrowserKit Testing是开源软件,许可证为MIT许可