测试响应
TestResponse 类提供了一系列实用方法,用于解析并验证测试用例返回的响应。通常,在进行 控制器测试 或 HTTP 功能测试 时会自动生成该对象,但也可以使用任何 ResponseInterface 实例直接创建:
$result = new \CodeIgniter\Test\TestResponse($response);
$result->assertOK();
测试响应
无论是通过测试获取还是手动创建的 TestResponse,都提供了一系列断言方法供测试使用。
访问请求/响应
request()
如果测试期间设置了 Request 对象,可直接进行访问:
$request = $results->request();
response()
用于直接访问 Response 对象:
$response = $results->response();
检查响应状态
isOK()
根据响应是否正常返回布尔值。判断标准主要是状态码是否在 200 或 300 范围内。除非是重定向,否则空的响应体会被视为无效。
if ($result->isOK()) {
// ...
}
assertOK()
此断言使用 isOK() 方法测试响应。assertNotOK() 是其反向断言。
$result->assertOK();
isRedirect()
根据响应是否为重定向返回布尔值。
if ($result->isRedirect()) {
// ...
}
assertRedirect()
断言响应为 RedirectResponse 实例。assertNotRedirect() 是其反向断言。
$result->assertRedirect();
assertRedirectTo()
断言响应为 RedirectResponse 实例,且目标地址与指定的 URI 匹配。
$result->assertRedirectTo('foo/bar');
getRedirectUrl()
返回 RedirectResponse 设置的 URL,失败时返回 null。
$url = $result->getRedirectUrl();
$this->assertEquals(site_url('foo/bar'), $url);
assertStatus(int $code)
断言返回的 HTTP 状态码与 $code 匹配。
$result->assertStatus(403);
Session 断言
assertSessionHas(string $key, $value = null)
断言最终的 Session 中存在指定键值。如果传入 $value,还会断言该变量的值与预期一致。
$result->assertSessionHas('logged_in', 123);
assertSessionMissing(string $key)
断言最终的 Session 中不包含指定的 $key。
$result->assertSessionMissing('logged_in');
HTTP 标头断言
assertHeader(string $key, $value = null)
断言响应中存在名为 $key 的 HTTP 标头。如果 $value 不为空,还将断言其值是否匹配。
$result->assertHeader('Content-Type', 'text/html');
assertHeaderMissing(string $key)
断言响应中不存在名为 $key 的 HTTP 标头。
$result->assertHeader('Accepts');
DOM 辅助方法
Response 对象包含多个辅助方法,用于检查响应中的 HTML 输出。这些方法在执行测试断言时非常有用。
see()
根据页面上是否存在指定文本返回布尔值。支持直接查找文本,或根据类型、class、id 在特定标签内查找:
// Check that "Hello World" is on the page
if ($results->see('Hello World')) {
// ...
}
// Check that "Hello World" is within an h1 tag
if ($results->see('Hello World', 'h1')) {
// ...
}
// Check that "Hello World" is within an element with the "notice" class
if ($results->see('Hello World', '.notice')) {
// ...
}
// Check that "Hello World" is within an element with id of "title"
if ($results->see('Hello World', '#title')) {
// ...
}
dontSee() 方法的效果则完全相反:
// Checks that "Hello World" does NOT exist on the page
if ($results->dontSee('Hello World')) {
// ...
}
// Checks that "Hellow World" does NOT exist within any h1 tag
if ($results->dontSee('Hello World', 'h1')) {
// ...
}
seeElement()
seeElement() 和 dontSeeElement() 与前述方法类似,但它们不比对元素的值,而仅检查元素是否存在于页面上:
// Check that an element with class 'notice' exists
if ($results->seeElement('.notice')) {
// ...
}
// Check that an element with id 'title' exists
if ($results->seeElement('#title')) {
// ...
}
// Verify that an element with id 'title' does NOT exist
if ($results->dontSeeElement('#title')) {
// ...
}
seeLink()
使用 seeLink() 确保页面上出现了包含指定文本的链接:
// Check that a link exists with 'Upgrade Account' as the text::
if ($results->seeLink('Upgrade Account')) {
// ...
}
// Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell'
if ($results->seeLink('Upgrade Account', '.upsell')) {
// ...
}
seeInField()
seeInField() 方法用于检查是否存在具有指定 name 和 value 的 input 标签:
// Check that an input exists named 'user' with the value 'John Snow'
if ($results->seeInField('user', 'John Snow')) {
// ...
}
// Check a multi-dimensional input
if ($results->seeInField('user[name]', 'John Snow')) {
// ...
}
seeCheckboxIsChecked()
使用 seeCheckboxIsChecked() 方法检查复选框是否存在且已被选中:
// Check if checkbox is checked with class of 'foo'
if ($results->seeCheckboxIsChecked('.foo')) {
// ...
}
// Check if checkbox with id of 'bar' is checked
if ($results->seeCheckboxIsChecked('#bar')) {
// ...
}
seeXPath()
Added in version 4.5.0.
使用 seeXPath() 可发挥 XPath 的强大功能。此方法面向高级用户,支持直接利用 DOMXPath 对象编写复杂的表达式:
// Check that h1 element which contains class "heading" is on the page
if ($results->seeXPath('//h1[contains(@class, "heading")]')) {
// ...
}
// Check that h1 element which contains class "heading" have a text "Hello World"
if ($results->seeXPath('//h1[contains(@class, "heading")][contains(.,"Hello world")]')) {
// ...
}
dontSeeXPath() 方法的效果则完全相反:
// Check that h1 element which contains class "heading" does NOT exist on the page
if ($results->dontSeeXPath('//h1[contains(@class, "heading")]')) {
// ...
}
// Check that h1 element which contains class "heading" and text "Hello World" does NOT exist on the page
if ($results->dontSeeXPath('//h1[contains(@class, "heading")][contains(.,"Hello world")]')) {
// ...
}
DOM 断言
可使用下列断言测试响应正文中是否存在特定的元素或文本。
assertSee(string $search = null, string $element = null)
断言页面上存在特定的文本或 HTML。支持直接查找,或根据类型、class、id 在特定标签内查找:
// Verify that "Hello World" is on the page
$result->assertSee('Hello World');
// Verify that "Hello World" is within an h1 tag
$result->assertSee('Hello World', 'h1');
// Verify that "Hello World" is within an element with the "notice" class
$result->assertSee('Hello World', '.notice');
// Verify that "Hello World" is within an element with id of "title"
$result->assertSee('Hello World', '#title');
assertDontSee(string $search = null, string $element = null)
断言效果与 assertSee() 方法完全相反:
// Verify that "Hello World" does NOT exist on the page
$results->assertDontSee('Hello World');
// Verify that "Hello World" does NOT exist within any h1 tag
$results->assertDontSee('Hello World', 'h1');
assertSeeElement(string $search)
与 assertSee() 类似,但仅检查元素是否存在,不检查具体的文本内容:
// Verify that an element with class 'notice' exists
$results->assertSeeElement('.notice');
// Verify that an element with id 'title' exists
$results->assertSeeElement('#title');
assertDontSeeElement(string $search)
与 assertSee() 类似,但仅检查指定的元素是否不存在,不检查具体的文本内容:
// Verify that an element with id 'title' does NOT exist
$results->assertDontSeeElement('#title');
assertSeeLink(string $text, string $details = null)
断言存在一个以 $text 作为正文的 a 标签:
// Verify that a link exists with 'Upgrade Account' as the text::
$results->assertSeeLink('Upgrade Account');
// Verify that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell'
$results->assertSeeLink('Upgrade Account', '.upsell');
assertSeeInField(string $field, string $value = null)
断言存在具有指定 name 和 value 的 input 标签:
// Verify that an input exists named 'user' with the value 'John Snow'
$results->assertSeeInField('user', 'John Snow');
// Verify a multi-dimensional input
$results->assertSeeInField('user[name]', 'John Snow');
处理 JSON
API 接口通常会返回 JSON 响应。下列方法可用于测试此类响应。
getJSON()
以 JSON 字符串形式返回响应正文:
/*
* Response body is this:
* ['foo' => 'bar']
*/
$json = $result->getJSON();
/*
* $json is this:
* {
* "foo": "bar"
* }
`*/
可使用此方法判断 $response 是否确实包含 JSON 内容:
// Verify the response is JSON
$this->assertTrue($result->getJSON() !== false);
备注
注意,结果中的 JSON 字符串将进行格式美化。
assertJSONFragment(array $fragment)
断言 JSON 响应中包含指定的 $fragment。无需匹配整个 JSON 值。
/*
* Response body is this:
* [
* 'config' => ['key-a', 'key-b'],
* ]
*/
// Is true
$result->assertJSONFragment(['config' => ['key-a']]);
assertJSONExact($test)
与 assertJSONFragment() 类似,但会检查整个 JSON 响应以确保完全匹配。
处理 XML
getXML()
如果应用返回 XML 内容,可通过此方法获取。