HTTP 功能测试

功能测试允许您查看对应用程序的单个调用的结果。这可能是返回单个 Web 表单的结果,命中 API 端点等等。这很方便,因为它允许您测试单个请求的整个生命周期,确保路由正常工作,响应格式正确,分析结果等等。

测试类

功能测试要求所有测试类都使用 CodeIgniter\Test\DatabaseTestTraitCodeIgniter\Test\FeatureTestTrait 特性。由于这些测试工具依赖于正确的数据库暂存,因此您必须始终确保 parent::setUp()parent::tearDown() 如果您实现了自己的方法,则会调用。

<?php

namespace App;

use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;

class TestFoo extends CIUnitTestCase
{
    use DatabaseTestTrait;
    use FeatureTestTrait;

    protected function setUp(): void
    {
        parent::setUp();

        $this->myClassMethod();
    }

    protected function tearDown(): void
    {
        parent::tearDown();

        $this->anotherClassMethod();
    }
}

请求页面

本质上,功能测试允许您调用应用程序上的端点并获取结果。为此,您使用 call() 方法。

  1. 第一个参数是要使用的 HTTP 方法(最常见的是 GET 或 POST)。

  2. 第二个参数是您要测试的网站上的 URI 路径。

  3. 第三个参数 $params 接受一个数组,用于填充您正在使用的 HTTP 动词的超全局变量。因此,GET 方法将填充 $_GET 变量,而 POST 请求将填充 $_POST 数组。 $params 也用于 格式化请求

    注意

    $params 数组并不适用于所有 HTTP 动词,但为了保持一致性而包含在内。

<?php

// Get a simple page
$result = $this->call('get', '/');

// Submit a form
$result = $this->call('post', 'contact', [
    'name'  => 'Fred Flintstone',
    'email' => '[email protected]',
]);

简写方法

每个 HTTP 动词都存在简写方法,以简化输入并使事情更清晰。

<?php

$this->get($path, $params);
$this->post($path, $params);
$this->put($path, $params);
$this->patch($path, $params);
$this->delete($path, $params);
$this->options($path, $params);

设置不同的路由

您可以通过将“路由”数组传递给 withRoutes() 方法来使用自定义路由集合。这将覆盖系统中任何现有的路由。

<?php

$routes = [
    ['get', 'users', 'UserController::list'],
];

$result = $this->withRoutes($routes)->get('users');

每个“路由”都是一个包含 3 个元素的数组,包含 HTTP 动词(或“add”表示所有)、要匹配的 URI 和路由目标。

设置会话值

您可以使用 withSession() 方法设置自定义会话值以在单个测试中使用。这将接受一个键值对数组,这些键值对应该在发出此请求时存在于 $_SESSION 变量中,或者 null 表示应使用 $_SESSION 的当前值。这对于测试身份验证等非常有用。

<?php

$values = [
    'logged_in' => 123,
];

$result = $this->withSession($values)->get('admin');

// Or...

$_SESSION['logged_in'] = 123;

$result = $this->withSession()->get('admin');

设置标头

您可以使用 withHeaders() 方法设置标头值。这将接受一个键值对数组,这些键值对将作为标头传递到调用中。

<?php

$headers = [
    'CONTENT_TYPE' => 'application/json',
];

$result = $this->withHeaders($headers)->post('users');

绕过事件

事件在您的应用程序中非常有用,但在测试期间可能存在问题。特别是用于发送电子邮件的事件。您可以使用 skipEvents() 方法告诉系统跳过任何事件处理。

<?php

$result = $this->skipEvents()->post('users', $userInfo);

格式化请求

您可以使用 withBodyFormat() 方法设置请求主体格式。目前支持 jsonxml。这在测试 JSON 或 XML API 时非常有用,这样您就可以以控制器期望的格式设置请求。

这将把传递给 call()post()get()… 的参数分配给给定格式的请求主体。

这也会相应地设置请求的 Content-Type 标头。

<?php

// If your feature test contains this:
$result = $this->withBodyFormat('json')->post('users', $userInfo);

// Your controller can then get the parameters passed in with:
$userInfo = $this->request->getJson();

设置主体

您可以使用 withBody() 方法设置请求主体。这允许您根据需要格式化主体。如果您有更复杂的 XML 要测试,建议您使用此方法。

这不会为您设置 Content-Type 标头。如果您需要它,您可以使用 withHeaders() 方法设置它。

检查响应

FeatureTestTrait::call() 返回一个 TestResponse 实例。有关如何使用此类在测试用例中执行其他断言和验证,请参阅 测试响应