HTTP 测试

简介

Laravel 为 HTTP 请求的生成和输出的检查都提供了非常流畅的 API。例如,你可以查看下面的这个测试用例:

  1. <?php
  2. namespace Tests\Feature;
  3. use Tests\TestCase;
  4. use Illuminate\Foundation\Testing\RefreshDatabase;
  5. use Illuminate\Foundation\Testing\WithoutMiddleware;
  6. class ExampleTest extends TestCase
  7. {
  8. /**
  9. * 一个基础的测试用例。
  10. *
  11. * @return void
  12. */
  13. public function testBasicTest()
  14. {
  15. $response = $this->get('/');
  16. $response->assertStatus(200);
  17. }
  18. }

get 方法会创建一个 GET 请求来请求你的应用,而 assertStatus 方法断言返回的响应是指定的 HTTP 状态码。除了这个简单的断言之外,Laravel 也包含检查响应标头、内容、JSON 结构等各种断言。

自定义请求头

您可以使用 withHeaders 方法在发送到应用程序之前自定义请求的标头。 你可以添加想要的任何自定义标题:

  1. <?php
  2. class ExampleTest extends TestCase
  3. {
  4. /**
  5. * 一个基本的功能测试示例。
  6. *
  7. * @return void
  8. */
  9. public function testBasicExample()
  10. {
  11. $response = $this->withHeaders([
  12. 'X-Header' => 'Value',
  13. ])->json('POST', '/user', ['name' => 'Sally']);
  14. $response
  15. ->assertStatus(200)
  16. ->assertJson([
  17. 'created' => true,
  18. ]);
  19. }
  20. }

{tip} 运行测试时,CSRF 中间件会自动禁用。

Session / 认证

Laravel 提供了几个可在测试时使用 Session 的辅助函数。首先,你需要传递一个数组给 withSession 方法来设置 Seesion 数据。这让你在应用程序的测试请求发送之前,先给数据加载 Session 变得简单:

  1. <?php
  2. class ExampleTest extends TestCase
  3. {
  4. public function testApplication()
  5. {
  6. $response = $this->withSession(['foo' => 'bar'])
  7. ->get('/');
  8. }
  9. }

当然,一般使用 Session 时都是用于维持用户的状态,如认证用户。actingAs 辅助函数提供了简单的方式来让指定的用户认证为当前的用户。例如,我们可以使用 工厂模型 来生成并认证用户:

  1. <?php
  2. use App\User;
  3. class ExampleTest extends TestCase
  4. {
  5. public function testApplication()
  6. {
  7. $user = factory(User::class)->create();
  8. $response = $this->actingAs($user)
  9. ->withSession(['foo' => 'bar'])
  10. ->get('/');
  11. }
  12. }

你也可以通过传递 guard 名称作为 actingAs 的第二参数以指定用户通过哪种 guard 来认证:

  1. $this->actingAs($user, 'api')

测试 JSON API

Laravel 也提供了几个辅助函数来测试JSON API 和它们的相应。例如 json, get, post, put, patchdelete 可以被用于发送各种 HTTP 动作。你也可以轻松地将数据和请求头传递到这些方法中。让我们写一个 POST 请求到 /user 并断言返回期望的数据来开始使用它们:

  1. <?php
  2. class ExampleTest extends TestCase
  3. {
  4. /**
  5. * 一个基础的功能测试示例。
  6. *
  7. * @return void
  8. */
  9. public function testBasicExample()
  10. {
  11. $response = $this->json('POST', '/user', ['name' => 'Sally']);
  12. $response
  13. ->assertStatus(200)
  14. ->assertJson([
  15. 'created' => true,
  16. ]);
  17. }
  18. }

{tip} assertJson 方法将响应转换为数组并且利用 PHPUnit::assertArraySubset 来验证给定的数组存在于应用返回的 JSON 响应中。所以,如果 JSON 相应中如果有其他属性,测试仍旧会在给定数组存在的情况下通过。

验证完全匹配

如果你想验证应用返回的 JSON 完全 匹配给定的数组,你应该使用 assertExactJson 方法:

  1. <?php
  2. class ExampleTest extends TestCase
  3. {
  4. /**
  5. * 一个基础的功能测试示例。
  6. *
  7. * @return void
  8. */
  9. public function testBasicExample()
  10. {
  11. $response = $this->json('POST', '/user', ['name' => 'Sally']);
  12. $response
  13. ->assertStatus(200)
  14. ->assertExactJson([
  15. 'created' => true,
  16. ]);
  17. }
  18. }

测试文件上传

进行测试时,这个 Illuminate\Http\UploadedFile 类提供了一个可能用来生成虚拟的文件或者图片的 fake 方法。它与这个 Storage Facade 的 fake 方法结合在一起巨大的简化了文件上传的测试。 例如 , 你可能把那两个特征结合起来很容易测试一个头像的上传成功:

  1. <?php
  2. namespace Tests\Feature;
  3. use Tests\TestCase;
  4. use Illuminate\Http\UploadedFile;
  5. use Illuminate\Support\Facades\Storage;
  6. use Illuminate\Foundation\Testing\RefreshDatabase;
  7. use Illuminate\Foundation\Testing\WithoutMiddleware;
  8. class ExampleTest extends TestCase
  9. {
  10. public function testAvatarUpload()
  11. {
  12. Storage::fake('avatars');
  13. $response = $this->json('POST', '/avatar', [
  14. 'avatar' => UploadedFile::fake()->image('avatar.jpg')
  15. ]);
  16. // 验证文件已存储 ...
  17. Storage::disk('avatars')->assertExists('avatar.jpg');
  18. // 验证一个文件不存在 ...
  19. Storage::disk('avatars')->assertMissing('missing.jpg');
  20. }
  21. }

虚拟文件定义

当使用这个 fake 方法创建文件时,为了更好地测试你想要的图片尺寸,你也许会设定图片的宽度,高度,以及图片的大小 :

  1. UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

此外,在进行创建图片时,你可能使用这个 create 方法创建其它任何类型的文件:

  1. UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

可用断言

响应断言

Laravel 为您的 PHPUnit 测试提供了各种常规断言方法。 这些断言可以通过从 json, get, post, put, 和 delete 测试方法返回的响应来访问:

assertCookieassertCookieExpiredassertCookieMissingassertDontSeeassertDontSeeTextassertExactJsonassertHeaderassertHeaderMissingassertJsonassertJsonFragmentassertJsonMissingassertJsonMissingExactassertJsonStructureassertJsonValidationErrorsassertPlainCookieassertRedirectassertSeeassertSeeInOrderassertSeeTextassertSeeTextInOrderassertSessionHasassertSessionHasAllassertSessionHasErrorsassertSessionHasErrorsInassertSessionMissingassertStatusassertSuccessfulassertViewHasassertViewHasAllassertViewIsassertViewMissing

断言此响应包含给定的 cookie

  1. $response->assertCookie($cookieName, $value = null);

断言此响应包含给定的 cookie 并且其已过期:

  1. $response->assertCookieExpired($cookieName);

断言此响应不包含给定的 cookie

  1. $response->assertCookieMissing($cookieName);

assertDontSee

验证所给的字符串不包含在响应中:

  1. $response->assertDontSee($value);

assertDontSeeText

验证所给的字符串不包含在响应的文本中:

  1. $response->assertDontSeeText($value);

assertExactJson

验证响应和所给 JSON 数据完全符合:

  1. $response->assertExactJson(array $data);

assertHeader

验证所给的头目前在响应中:

  1. $response->assertHeader($headerName, $value = null);

assertHeaderMissing

验证所给的头目前没有在响应中:

  1. $response->assertHeaderMissing($headerName);

assertJson

验证响应包含所给的 JSON 数据:

  1. $response->assertJson(array $data);

assertJsonFragment

验证此响应包含给定的 JSON 片段:

  1. $response->assertJsonFragment(array $data);

assertJsonMissing

验证此响应不包含给定的 JSON 片段:

  1. $response->assertJsonMissing(array $data);

assertJsonMissingExact

验证此响应不包含确切的 JSON 片段

  1. $response->assertJsonMissingExact(array $data);

assertJsonStructure

验证此响应含有给定的 JSON 结构:

  1. $response->assertJsonStructure(array $structure);

assertJsonValidationErrors

验证此响应有给定键的 JSON 验证错误 :

  1. $response->assertJsonValidationErrors($keys);

assertPlainCookie

验证此响应包含所给的 cookie 『 加密 』:

  1. $response->assertPlainCookie($cookieName, $value = null);

assertRedirect

断言响应重定向到指定 URI:

  1. $response->assertRedirect($uri);

assertSee

断言响应中包含指定字符串:

  1. $response->assertSee($value);

assertSeeInOrder

断言响应中有序包含指定字符串:

  1. $response->assertSeeInOrder(array $values);

assertSeeText

断言响应文本中包含指定字符串:

  1. $response->assertSeeText($value);

assertSeeTextInOrder

断言响应文本中有序包含指定字符串:

  1. $response->assertSeeTextInOrder(array $values);

assertSessionHas

断言 session 包含数据片段:

  1. $response->assertSessionHas($key, $value = null);

assertSessionHasAll

断言 session 中存在指定的所有值:

  1. $response->assertSessionHasAll($key, $value = null);

assertSessionHasErrors

断言 session 中含有指定错误:

  1. $response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');

assertSessionHasErrorsIn

断言 session 中含有指定错误:

  1. $response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);

assertSessionMissing

断言 session 中不含有指定键:

  1. $response->assertSessionMissing($key);

assertStatus

断言响应中存在指定状态码:

  1. $response->assertStatus($code);

assertSuccessful

断言响应中存在成功状态码:

  1. $response->assertSuccessful();

assertViewHas

断言响应视图中存在指定数据片段:

  1. $response->assertViewHas($key, $value = null);

assertViewHasAll

断言响应视图中存在指定的所有数据:

  1. $response->assertViewHasAll(array $data);

assertViewIs

断言响应视图与指定值一致:

  1. $response->assertViewIs($value);

assertViewMissing

断言响应视图缺少一个绑定的数据:

  1. $response->assertViewMissing($key);

认证断言

Laravel 为您的 PHPUnit 测试提供了多种身份认证相关的断言:

方法描述
$this->assertAuthenticated($guard = null);断言此用户已被认证
$this->assertGuest($guard = null);断言此用户未被认证
$this->assertAuthenticatedAs($user, $guard = null);断言给定的用户被认证
$this->assertCredentials(array $credentials, $guard = null);断言给定的凭证有效
$this->assertInvalidCredentials(array $credentials, $guard = null);断言给定的凭证无效

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。