HTTP 功能测试
功能测试用于查看应用程序单次调用的执行结果,涵盖返回单个 Web 表单结果、访问 API 接口等场景。此功能非常实用,支持测试单个请求的完整生命周期,从而确保路由正常工作、响应格式正确,并可对执行结果进行分析。
测试类
进行功能测试时,所有测试类均须使用 CodeIgniter\Test\DatabaseTestTrait 与 CodeIgniter\Test\FeatureTestTrait。鉴于这些测试工具依赖正确的数据库初始化,若在类中重写了相关方法,务必确保调用 parent::setUp() 与 parent::tearDown()。
<?php
namespace Tests\Feature;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
class FooTest extends CIUnitTestCase
{
use DatabaseTestTrait;
use FeatureTestTrait;
protected function setUp(): void
{
parent::setUp();
$this->myClassMethod();
}
protected function tearDown(): void
{
parent::tearDown();
$this->anotherClassMethod();
}
}
请求页面
功能测试本质上就是调用应用上的某个接口并返回结果。为此,可使用 call() 方法。
第一个参数是要使用的 HTTP 方法(最常用的是
GET或POST)。第二个参数是要测试的站点 URI 路径。
第三个参数
$params接受一个数组,用于填充所使用的 HTTP 方法对应的超全局 变量。因此,GET 方法会填充$_GET变量,而 POST 请求则会填充$_POST数组。$params也可用于 格式化请求。备注
$params数组并不适用于所有 HTTP 方法,但为保持一致性而保留。
// Get a simple page
$result = $this->call('GET', '/');
// Submit a form
$result = $this->call('post', 'contact', [
'name' => 'Fred Flintstone',
'email' => 'flintyfred@example.com',
]);
快捷方法
为每个 HTTP 方法提供了快捷方法,以简化输入并使意图更清晰:
$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() 方法来使用自定义路由集合,该方法会覆盖
系统中任何现有的路由:
$routes = [
['GET', 'users', 'UserController::list'],
];
$result = $this->withRoutes($routes)->get('users');
每个「路由」是一个包含 3 个元素的数组,包含 HTTP 方法(或使用 “add” 表示所有)、 要匹配的 URI 以及路由目标。
设置 Session 值
可以使用 withSession() 方法在单个测试期间设置自定义 Session 值。该方法接受一个关联数组,
这些值在发出请求时会存在于 $_SESSION 变量中;也可传入 null,
表示使用 $_SESSION 的当前值。这对于测试认证等场景很有用。
$values = [
'logged_in' => 123,
];
$result = $this->withSession($values)->get('admin');
// Or...
$_SESSION['logged_in'] = 123;
$result = $this->withSession()->get('admin');
设置 Header
使用 withHeaders() 方法可设置 Header 值。该方法接收一个关联数组,并将其作为 Header 随请求一同发送:
$headers = [
'CONTENT_TYPE' => 'application/json',
];
$result = $this->withHeaders($headers)->post('users');
跳过事件
事件在应用中很有用,但在测试期间可能会带来问题。尤其是用于发送邮件的事件。可以
使用 skipEvents() 方法告诉系统跳过任何事件处理:
$result = $this->skipEvents()->post('users', $userInfo);
格式化请求
使用 withBodyFormat() 方法可设置请求体格式,目前支持 json 与 xml。
在测试 JSON 或 XML API 时,此功能可按控制器预期的格式构造请求。
该方法会自动将传给 call()、post() 或 get() 等方法的参数,按指定格式转换并填入请求体。
同时自动设置相应的 Content-Type 标头。
// 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 实例。有关如何在测试用例中
使用此类执行额外断言和验证,请参阅 测试响应。