HTTP 測試
HTTP 測試
HTTP Tests
簡介
Laravel 為 HTTP 請求的生成和輸出的檢查都提供了非常流暢的 API。例如,你可以查看下面的這個測試用例:
<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; class ExampleTest extends TestCase{ /** * 一個基礎的測試用例。 * * @return void */ public function testBasicTest() { $response = $this->get('/'); $response->assertStatus(200); } }
get
方法會創(chuàng)建一個 GET
請求來請求你的應用,而 assertStatus
方法斷言返回的響應是指定的 HTTP 狀態(tài)碼。 除了這個簡單的斷言之外, Laravel 也包含檢查響應標頭、內容、JSON、結構等各種斷言。
自定義請求頭
你可以使用 withHeaders
方法在發(fā)送到應用程式之前自定義請求的標頭。 你可以添加想要的任何自定義標頭。
<?php class ExampleTest extends TestCase{ /** * 一個基礎的功能測試用例。 * * @return void */ public function testBasicExample() { $response = $this->withHeaders([ 'X-Header' => 'Value', ])->json('POST', '/user', ['name' => 'Sally']); $response ->assertStatus(201) ->assertJson([ 'created' => true, ]); } }
{tip} 運行測試時,CSRF 中間件會自動禁用。
Session / 認證
Laravel 提供了幾個可在 HTTP 測試時使用 Session 的輔助函數(shù)。首先,你需要傳遞一個數(shù)組給 withSession
方法來設置 Session 數(shù)據。這讓你在應用程序的測試請求發(fā)送之前,先給數(shù)據加載 Session 變得簡單:
<?php class ExampleTest extends TestCase{ public function testApplication() { $response = $this->withSession(['foo' => 'bar']) ->get('/'); } }
當然,一般使用 Session 時都是用于維護用戶狀態(tài),如認證用戶。actingAs
輔助函數(shù)提供了簡單的方法來指定的用戶認證為當前用戶。 例如, 我們可以使用 工廠模型 來生成并認證用戶:
<?php use App\User; class ExampleTest extends TestCase{ public function testApplication() { $user = factory(User::class)->create(); $response = $this->actingAs($user) ->withSession(['foo' => 'bar']) ->get('/'); } }
你也可以通過傳遞看守器名稱作為 actingAs
的第二參數(shù)以指定用戶通過哪種看守器來認證:
$this->actingAs($user, 'api')
測試 JSON APIs
Laravel 也提供了幾個輔助函數(shù)來測試 JSON APIs 和他們的響應。 例如,json
, get
, post
, put
, patch
,和 delete
可以被用于發(fā)送各種 HTTP 動作。 你也可以輕松地將數(shù)據和請求頭傳遞到這些方法中。讓我們寫一個 POST
請求到 /user
并斷言返回期望的數(shù)據來開始使用他們:
<?php class ExampleTest extends TestCase{ /** * 一個簡單的功能測試用例。 * * @return void */ public function testBasicExample() { $response = $this->json('POST', '/user', ['name' => 'Sally']); $response ->assertStatus(201) ->assertJson([ 'created' => true, ]); } }
{tip}
assertJson
方法將響應轉換為數(shù)組并利用PHPUnit::assertArraySubset
來驗證給定的數(shù)組存在于應用返回的 JSON 響應中。 所以,如果 JSON 響應中有其他屬性,測試仍舊會在給定數(shù)組存在的情況下通過:
驗證完全匹配
如果你想驗證給定的數(shù)組 完全 匹配應用返回的 JSON 結果,你應該使用 assertExactJson
方法:
<?php class ExampleTest extends TestCase{ /** * 一個基本的功能測試用例。 * * @return void */ public function testBasicExample() { $response = $this->json('POST', '/user', ['name' => 'Sally']); $response ->assertStatus(201) ->assertExactJson([ 'created' => true, ]); } }
測試文件上傳
Illuminate\Http\UploadedFile
提供了一個 fake
方法用于生成虛擬的文件或者圖像以供測試之用。 它可以和 Storage
facade 的 fake
方法相結合, 大幅度簡化了文件上傳測試。舉個例子,你可以結合這兩者的功能非常方便地進行頭像上傳表單測試:
<?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, ]); // 斷言文件已經存儲 . . . Storage::disk('avatars')->assertExists($file->hashName()); // 斷言文件不存在 . . . Storage::disk('avatars')->assertMissing('missing.jpg'); } }
虛擬文件制定
在使用 fake
方法創(chuàng)建文件時,你可以指定圖像的寬高以及大小,從而更好的驗證測試規(guī)則:
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
除創(chuàng)建圖像外,你也可以用 create
方法創(chuàng)建其他類型的文件:
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);
可用斷言
響應斷言
Laravel 給 PHPUnit 測試提供了各種各樣的常用斷言方法??蓮?json
, get
, post
, put
,和 delete
測試方法中訪問這些斷言:
assertCookie
assertCookieExpired
assertCookieNotExpired
assertCookieMissing
assertDontSee
assertDontSeeText
assertExactJson
assertForbidden
assertHeader
assertHeaderMissing
assertJson
assertJsonCount
assertJsonFragment
assertJsonMissing
assertJsonMissingExact
assertJsonMissingValidationErrors
assertJsonStructure
assertJsonValidationErrors
assertLocation
assertNotFound
assertOk
assertPlainCookie
assertRedirect
assertSee
assertSeeInOrder
assertSeeText
assertSeeTextInOrder
assertSessionHas
assertSessionHasAll
assertSessionHasErrors
assertSessionHasErrorsIn
assertSessionHasNoErrors
assertSessionDoesntHaveErrors
assertSessionMissing
assertStatus
assertSuccessful
assertViewHas
assertViewHasAll
assertViewIs
assertViewMissing
assertCookie
斷言響應中包含給定的 cookie:
$response->assertCookie($cookieName, $value = null);
assertCookieExpired
斷言響應中包含了給定的 cookie 且它已過期:
$response->assertCookieExpired($cookieName);
assertCookieNotExpired
斷言響應中包含了給定的 cookie 且它未過期:
$response->assertCookieNotExpired($cookieName);
assertCookieMissing
斷言響應中不包含給定的 cookie:
$response->assertCookieMissing($cookieName);
assertDontSee
斷言響應中不包含給定的字符串:
$response->assertDontSee($value);
assertDontSeeText
斷言給定字符串不包含在響應文本中:
$response->assertDontSeeText($value);
assertExactJson
斷言響應中包含的數(shù)據與給定的 JSON 數(shù)據完全匹配:
$response->assertExactJson(array $data);
assertForbidden
斷言響應中有禁止狀態(tài)碼:
$response->assertForbidden();
assertHeader
斷言響應中有給定的包頭:
$response->assertHeader($headerName, $value = null);
assertHeaderMissing
斷言響應中沒有給定的報頭:
$response->assertHeaderMissing($headerName);
assertJson
斷言響應包含給定的 JSON 數(shù)據:
$response->assertJson(array $data);
assertJsonCount
斷言響應 JSON 中有一個數(shù)組,其中包含給定鍵的預期元素數(shù)量:
$response->assertJsonCount($count, $key = null);
assertJsonFragment
斷言響應包含給定 JSON 片段:
$response->assertJsonFragment(array $data);
assertJsonMissing
斷言響應未包含給定的 JSON 片段:
$response->assertJsonMissing(array $data);
assertJsonMissingExact
斷言響應不包含確切的 JSON 片段:
$response->assertJsonMissingExact(array $data);
assertJsonMissingValidationErrors
斷言響應沒有給定鍵的 JSON 驗證錯誤:
$response->assertJsonMissingValidationErrors($keys);
assertJsonStructure
斷言響應具有給定的 JSON 結構:
$response->assertJsonStructure(array $structure);
assertJsonValidationErrors
斷言響應具有給定鍵的給定 JSON 驗證錯誤:
$response->assertJsonValidationErrors($keys);
assertLocation
斷言響應在 Location
頭部中具有給定的 URI 值:
$response->assertLocation($uri);
assertNotFound
斷言響應具有未找到狀態(tài)碼:
$response->assertNotFound();
assertOk
斷言響應有 200 狀態(tài)碼:
$response->assertOk();
assertPlainCookie
斷言響應包含給定的 cookie (未加密):
$response->assertPlainCookie($cookieName, $value = null);
assertRedirect
斷言響應會重定向到給定的 URI:
$response->assertRedirect($uri);
assertSee
斷言給定的字符串包含在響應中:
$response->assertSee($value);
assertSeeInOrder
斷言響應中有序包含了給定的字符串:
$response->assertSeeInOrder(array $values);
assertSeeText
斷言給定的字符串包含在響應文本中:
$response->assertSeeText($value);
assertSeeTextInOrder
斷言給定的字符串有序包含在響應文本中:
$response->assertSeeTextInOrder(array $values);
assertSessionHas
斷言 session 中包含給定的數(shù)據:
$response->assertSessionHas($key, $value = null);
assertSessionHasAll
斷言 session 中有給定值列表:
$response->assertSessionHasAll(array $data);
assertSessionHasErrors
斷言 session 中包含一個給定字段的錯誤:
$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');
assertSessionHasErrorsIn
斷言 session 中具有給定的錯誤:
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
assertSessionHasNoErrors
斷言 session 沒有錯誤:
$response->assertSessionHasNoErrors();
assertSessionDoesntHaveErrors
斷言 session 沒有給定鍵錯誤:
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
assertSessionMissing
斷言 session 中不包含給定鍵:
$response->assertSessionMissing($key);
assertStatus
斷言響應中具有給定的狀態(tài)碼:
$response->assertStatus($code);
assertSuccessful
斷言響應中有成功的狀態(tài)碼:
$response->assertSuccessful();
assertViewHas
斷言響應視圖是一段給定的數(shù)據:
$response->assertViewHas($key, $value = null);
assertViewHasAll
斷言響應視圖具有給定的數(shù)據列表:
$response->assertViewHasAll(array $data);
assertViewIs
斷言路由返回給定的視圖:
$response->assertViewIs($value);
assertViewMissing
斷言響應視圖缺少一段綁定數(shù)據:
$response->assertViewMissing($key);
Authentication Assertions
Laravel 還為你的 PHPUnit 測試提供了各種與身份驗證相關的斷言:
Method | Description |
---|---|
$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); | 斷言給定的憑證無效。 |