Laravel: Test HTTP
Giải phóng thời gian, khai phóng năng lực
Mục lục bài viết
Giới thiệu
Laravel cung cấp một API rất tuyệt vời để tạo các request HTTP tới ứng dụng và kiểm tra output. Ví dụ sau đây định nghĩa một test:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
Phương thức get
method tạo một request GET
vào ứng dụng, còn phương thức assertStatus
xác nhận response cần có mã trạng thái HTTP đã cho. Ngoài xác nhận đơn giản này thì Laravel còn chứa một loạt các xác nhận khác để test các header, content, cấu trúc JSON, ...
Tùy chỉnh Request Headers
Ta có thể sử dụng phương thức withHeaders
để tùy chỉnh các header của request trước khi gửi nó tới ứng dụng. Điều này sẽ cho phép ta thêm bất kỳ header tùy chỉnh nào ta muốn cho request:
<?php
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->withHeaders([
'X-Header' => 'Value',
])->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
Middleware CSRF sẽ tự động được disable khi chạy test.
Session / Authentication
Laravel cung cấp một số helper để làm việc với session khi test HTTP. Trước tiên ta cần thiết lập data session tới một mảng đã cho bằng việc sử dụng phương thức withSession
. Việc này rất hữu dụng khi tải session với data trước khi tạo request tới ứng dụng:
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$response = $this->withSession(['foo' => 'bar'])
->get('/');
}
}
Thường thì session dùng để duy trì trạng thái cho người dùng đã được xác thực. Phương thức hỗ trợ actingAs
cung cấp một cách khá đơn giản để xác thực người dùng. Ví dụ, ta có thể sử dụng model factory để tạo và xác thực người dùng như sau:
<?php
use App\User;
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = factory(User::class)->create();
$response = $this->actingAs($user)
->withSession(['foo' => 'bar'])
->get('/');
}
}
Ta cũng có thể chỉ định guard nào cần được dùng để xác thực người dùng bằng cách truyền tên của guard là tham số thứ 2 của phương thức actingAs
:
$this->actingAs($user, 'api')
Test JSON API
Laravel cũng cung cấp một số trình hỗ trợ để test JSON API và các response của chúng. Ví dụ các phương thức json
, get
, post
, put
, patch
, và delete
có thể được dùng để tạo requests tới các HTTP. Ta cũng có thể dễ dàng truyền dữ liệu và các header tới các phương thức này. Để bắt đầu thì ta hay viết một test để tạo một request POST
tới /user
và xác nhận dữ liệu dự kiến được trả về:
<?php
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
Phương thứcassertJson
sẽ chuyển response thành một mảng và sử dụngPHPUnit::assertArraySubset
để xác minh mảng đã cho là có sẵn trong response JSON được trả vè bằng ứng dụng. Cho nên, nếu có các thuộc tính khác trong response JSON thì test trên sẽ vẫn hoàn tất miễn là có đoạn đã cho.
Xác nhận đúng là JSON
Nếu ta muốn xác nhận rằng mảng đã cho chính xác là một JSON được trả về bởi ứng dụng thì ta cần sử dụng phương thức assertExactJson
:
<?php
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
}
}
Test File upload
Class Illuminate\Http\UploadedFile
cung cấp một phương thức fake
có thể dùng để tạo các file giả hoặc ảnh để test. Khi kết hợp với phương thức fake
của facade Storage
sẽ giúp ta đơn giản hóa việc test file upload. Ví dụ, ta có thể kết hợp 2 đặc điểm này để dễ dàng test một form upload avatar:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class ExampleTest extends TestCase
{
public function testAvatarUpload()
{
Storage::fake('avatars');
$file = UploadedFile::fake()->image('avatar.jpg');
$response = $this->json('POST', '/avatar', [
'avatar' => $file,
]);
// Assert the file was stored...
Storage::disk('avatars')->assertExists($file->hashName());
// Assert a file does not exist...
Storage::disk('avatars')->assertMissing('missing.jpg');
}
}
Tùy chỉnh file giả
Khi tạo các file sử dụng phương thức fake
thì ta có thể chỉ định chiều rộng, chiều cao và size của anh để test tốt hơn các quy tắc xác thực của ta:
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
Cùng với việc tạo ảnh thì ta có thể tạo các file với kiểu bất kỳ sử dung phương thức create
:
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);
Các Assertion sẵn có
Assetion Response
Laravel cung cấp một số phương thức assertion tùy chỉnh cho việc test PHPUnit. Các assertion này có thể được truy cập trên các response được trả về từ các phương thức test json
, get
, post
, put
, và delete
:
assertCookie
Xác nhận response có chứa cookie đã cho:
$response->assertCookie($cookieName, $value = null);
assertCookieExpired
Xác nhận response có chứa cookie đã cho và nó đã hết hạn:
$response->assertCookieExpired($cookieName);
assertCookieNotExpired
Xác nhận response có chứa cookie đã cho và nó chưa hết hạn:
$response->assertCookieNotExpired($cookieName);
assertCookieMissing
Xác nhận response không chứa cookie đã cho:
$response->assertCookieMissing($cookieName);
assertDontSee
Xác nhận rằng chuỗi đã cho không nằm trong response:
$response->assertDontSee($value);
assertDontSeeText
Xác nhận rằng chuỗi đã cho không nằm trong response text:
$response->assertDontSeeText($value);
assertExactJson
Xác nhận rằng response chứa một tương thích chính xác của data JSON đã cho:
$response->assertExactJson(array $data);
assertForbidden
Xác nhận rằng response cho một mã trạng thái bị cấm:
$response->assertForbidden();
assertHeader
Xác nhận rằng header đã cho có trong response:
$response->assertHeader($headerName, $value = null);
assertHeaderMissing
Xác nhận rằng header đã cho không có trong response:
$response->assertHeaderMissing($headerName);
assertJson
Xác nhận rằng response có chứa data JSON đã cho:
$response->assertJson(array $data);
assertJsonCount
Xác nhận rằng response JSON có một mảng với số lượng mục dữ kiến tại key đã cho:
$response->assertJsonCount($count, $key = null);
assertJsonFragment
Xác nhận rằng response chưa đoạn JSON đã cho:
$response->assertJsonFragment(array $data);
assertJsonMissing
Xác nhận rằng response không chứa đoạn JSON đã cho:
$response->assertJsonMissing(array $data);
assertJsonMissingExact
Xác nhận rằng response không chứa đoạn JSON chính xác:
$response->assertJsonMissingExact(array $data);
assertJsonStructure
Xác nhận rằng response có cấu trúc JSON đã cho:
$response->assertJsonStructure(array $structure);
assertJsonValidationErrors
Xác nhận rằng response có các lỗi xác thực JSON đã cho cho các key đã cho:
$response->assertJsonValidationErrors($keys);
assertLocation
Xác nhận rằng response có giá trị URL đã cho trong header Location
:
$response->assertLocation($uri);
assertNotFound
Xác nhận rằng response có một mã trạng thái không tìm thấy:
$response->assertNotFound();
assertOk
Xác nhận rằng response có một mã trạng thái 200:
$response->assertOk();
assertPlainCookie
Xác nhận rằng response chứa cookie đã cho (không được mã hóa):
$response->assertPlainCookie($cookieName, $value = null);
assertRedirect
Xác nhận rằng response là một request tới URI đã cho:
$response->assertRedirect($uri);
assertSee
Xác nhận rằng chuỗi đã cho nằm trong response:
$response->assertSee($value);
assertSeeInOrder
Xác nhận rằng các chuỗi đã cho nằm trong response:
$response->assertSeeInOrder(array $values);
assertSeeText
Xác nhận rằng chuỗi đã cho nằm trong response text:
$response->assertSeeText($value);
assertSeeTextInOrder
Xác nhận rằng các chuỗi đã cho nằm trong response text:
$response->assertSeeTextInOrder(array $values);
assertSessionHas
Xác nhận rằng session chứa phần dữ liệu đã cho:
$response->assertSessionHas($key, $value = null);
assertSessionHasAll
Xác nhận rằng session có một danh sách các giá trị đã cho:
$response->assertSessionHasAll(array $data);
assertSessionHasErrors
Xác nhận rằng session chứa một lỗi ứng với trường đã cho:
$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');
assertSessionHasErrorsIn
Xác nhận rằng session có các lỗi đã cho:
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
assertSessionHasNoErrors
Xác nhận rằng session không có lỗi:
$response->assertSessionHasNoErrors();
assertSessionMissing
Xác nhận rằng session không chứa key đã cho:
$response->assertSessionMissing($key);
assertStatus
Xác nhận rằng response có mã lệnh đã cho:
$response->assertStatus($code);
assertSuccessful
Xác nhận rằng response có một mã trạng thái thành công:
$response->assertSuccessful();
assertViewHas
Xác nhận rằng response view được cho một phần của dữ liệu:
$response->assertViewHas($key, $value = null);
assertViewHasAll
Xác nhận rằng response view có một danh sách dữ liệu đã cho:
$response->assertViewHasAll(array $data);
assertViewIs
Xác nhận rằng view đã cho được trả về bởi route:
$response->assertViewIs($value);
assertViewMissing
Xác nhận rằng response view đang thiếu một phần dữ liệu ràng buộc:
$response->assertViewMissing($key);
Xác nhận xác thực
Laravel cũng cung cấp các xác nhận liên quan đến việc xác thực cho các test PHPUnit:
Phương thức | Mô tả |
---|---|
$this->assertAuthenticated($guard = null); |
Xác nhận rằng người dùng đã được xác thực. |
$this->assertGuest($guard = null); |
Xác nhận rằng người dùng không được xác thực. |
$this->assertAuthenticatedAs($user, $guard = null); |
Xác nhận rằng người dùng đã cho được xác thực. |
$this->assertCredentials(array $credentials, $guard = null); |
Xác nhận rằng các thông tin đã cho là hợp lệ. |
$this->assertInvalidCredentials(array $credentials, $guard = null); |
Xác nhận rằng các thông tin đã cho không hợp lệ. |
Giải phóng thời gian, khai phóng năng lực