CodeIgniter4 HTTP 测试

2020-08-17 17:46 更新

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

测试类

功能测试要求您所有的测试类都对该CodeIgniter\Test\FeatureTestCase类进行扩展。由于这扩展了CIDatabaseTestCase,因此您必须始终确保 在执行操作之前调用parent::setUp()parent::tearDown()

<?php namespace App;


use CodeIgniter\Test\FeatureTestCase;


class TestFoo extends FeatureTestCase
{
    public function setUp()
    {
        parent::setUp();
    }


    public function tearDown()
    {
        parent::tearDown();
    }
}

请求页面

本质上,FeatureTestCase仅允许您在应用程序上调用终结点并返回结果。为此,您可以使用call()方法。第一个参数是要使用的HTTP方法(最常见的是GET或POST)。第二个参数是您网站上要测试的路径。第三个参数接受一个数组,该数组用于填充您正在使用的HTTP动词的超全局变量。因此,GET方法将填充$ _GET变量,而发布请求将填充$ _POST数组。

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


// Submit a form
$result = $this->call('post', site_url('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);

注解

$ params数组并不是每个HTTP动词都有意义,但为了保持一致性而包含了该数组。

设定不同的路线

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

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


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

每个“路由”都是一个3元素数组,包含HTTP动词(或全部为“添加”),要匹配的URI和路由目的地。

设置会话值

您可以使用方法设置自定义会话值,以在单个测试中使用withSession()。发出此请求时,这需要键/值对的数组,这些键/值对应存在于$ _SESSION变量中。这对于测试身份验证非常方便。

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


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

绕过事件

事件很容易在您的应用程序中使用,但在测试过程中可能会出现问题。尤其是用于发送电子邮件的事件。您可以使用以下skipEvents()方法告诉系统跳过任何事件处理:

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

测试响应

执行一个 call()并获得结果后,可以在测试中使用许多新的断言。

注解

响应对象可从公开获得$result-&response。如果需要,可以使用该实例对它执行其他声明。

检查响应状态

isOK()

根据响应是否被认为是“ ok”,返回布尔值true / false。这主要由200或300的响应状态代码确定。

if ($result->isOK())
{
    ...
}

assertOK()

该论断仅使用isOK()方法来测试响应。

$this->assertOK();

isRedirect()

根据响应是否为重定向响应,返回布尔值true / false。

if ($result->isRedirect())
{
    ...
}

assertRedirect()

论断该响应是RedirectResponse的一个实例。

$this->assertRedirect();

assertStatus(int $code)

论断返回的HTTP状态代码与$ code相匹配。

$this->assertStatus(403);

会议断言

assertSessionHas(string $key, $value = null)

断言结果会话中存在值。如果传递了$ value,还将断言该变量的值与指定的值匹配。

$this->assertSessionHas('logged_in', 123);

assertSessionMissing(string $key)

断言结果会话不包含指定的$ key。

$this->assertSessionMissin('logged_in');

标头断言

assertHeader(string $key, $value = null)

断言响应中存在名为$ key的标头。如果$ value不为空,还将断言这些值匹配。

$this->assertHeader('Content-Type', 'text/html');

assertHeaderMissing(string $key)

断言响应中不存在标头名称$ key

$this->assertHeader('Accepts');

Cookie断言

assertCookie(string $key, $value = null, string $prefix = ‘’)

断言响应中存在一个名为$ key的cookie 。如果$ value不为空,还将断言这些值匹配。您可以根据需要通过将cookie前缀作为第三个参数传递来设置它。

$this->assertCookie('foo', 'bar');

assertCookieMissing(string $key)

断言响应中不存在名为$ key的cookie 。

$this->assertCookieMissing('ci_session');

assertCookieExpired(string $key, string $prefix = ‘’)

断言存在一个名为$ key的cookie ,但已过期。您可以根据需要通过将cookie前缀作为第二个参数传递来设置它。

$this->assertCookieExpired('foo');

DOM论断

您可以执行测试,以查看带有以下声明的响应的正文中是否存在特定的元素/文本/等。

assertSee(string $search = null, string $element = null)

断言文本/ HTML是否在页面上,无论是本身,还是(更具体而言)在标签内,由类型,类或id指定:

// Check that "Hello World" is on the page
$this->assertSee('Hello World');
// Check that "Hello World" is within an h1 tag
$this->assertSee('Hello World', 'h1');
// Check that "Hello World" is within an element with the "notice" class
$this->assertSee('Hello World', '.notice');
// Check that "Hello World" is within an element with id of "title"
$this->assertSee('Hellow World', '#title');

assertDontSee(string $search = null, string $element = null)

声明与assertSee()方法完全相反的地方:

// Checks that "Hello World" does NOT exist on the page
$results->dontSee('Hello World');
// Checks that "Hello World" does NOT exist within any h1 tag
$results->dontSee('Hello World', 'h1');

assertSeeElement(string $search)

assertSee()类似,但是这仅检查现有元素。它不检查特定的文本:

// Check that an element with class 'notice' exists
$results->seeElement('.notice');
// Check that an element with id 'title' exists
$results->seeElement('#title')

assertDontSeeElement(string $search)

assertSee()类似,但是这仅检查缺少的现有元素。它不检查特定的文本:

// Verify that an element with id 'title' does NOT exist
$results->dontSeeElement('#title');

assertSeeLink(string $text, string $details=null)

断言找到一个匹配标签为$ text的锚标签:

// Check that a link exists with 'Upgrade Account' as the text::
$results->seeLink('Upgrade Account');
// Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell'
$results->seeLink('Upgrade Account', '.upsell');

assertSeeInField(string $field, string $value=null)

断言输入标签具有名称和值:

// Check that an input exists named 'user' with the value 'John Snow'
$results->seeInField('user', 'John Snow');
// Check a multi-dimensional input
$results->seeInField('user[name]', 'John Snow');

使用JSON

响应通常包含JSON响应,尤其是在使用API方法时。以下方法可以帮助测试响应。

getJSON()

此方法将以JSON字符串的形式返回响应的主体:

// Response body is this:
['foo' => 'bar']


$json = $result->getJSON();


// $json is this:
{
    "foo": "bar"
}

注解

请注意,JSON字符串将漂亮地打印在结果中。

assertJSONFragment(array $fragment)

断言$fragment在JSON响应中找到。它不需要匹配整个JSON值。

// Response body is this:
[
    'config' => ['key-a', 'key-b']
]


// Is true
$this->assertJSONFragment(['config' => ['key-a']);

注解

这只是使用phpUnit自己的assertArraySubset() 方法进行比较。

assertJSONExact($test)

assertJSONFragment()相似,但是检查整个JSON响应以确保完全匹配。

使用XML

getXML()

如果您的应用程序返回XML,则可以通过此方法检索它。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号