laravel / browser-kit-testing

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

v7.2.0 2024-02-09 15:16 UTC

README

Build Status Total Downloads Latest Stable Version License

介绍

Laravel BrowserKit Testing提供了一个非常流畅的API,用于向应用程序发送HTTP请求、检查输出结果,甚至填写表单。

官方文档

安装

首先,安装此包

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 = 'http://localhost';

    // ...
}

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

使用

要了解一个简单的示例,请查看下面的测试定义

<?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属性和嵌套的pet对象,该对象具有自己的nameage属性。seeJsonStructure不会因响应中存在额外的键而失败。例如,如果pet具有weight属性,则测试仍会通过。

您可以使用*来断言返回的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测试提供了一系列自定义断言方法

贡献

感谢您考虑为BrowserKit Testing做出贡献!贡献指南可以在Laravel文档中找到。

行为准则

为了确保Laravel社区对所有人都友好,请查阅并遵守行为准则

安全漏洞

请审查我们的安全策略,了解如何报告安全漏洞。我们的安全策略链接

许可证

Laravel BrowserKit Testing 是开源软件,遵循MIT 许可协议