HTTP 測試
簡介
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
方法會建立一個GET
請求來請求你的應用,而assertStatus
方法斷言傳回的回應是指定的HTTP 狀態碼。除了這個簡單的斷言之外, Laravel 還包含檢查回應標頭、內容、JSON、結構等各種斷言。
自訂請求頭
你可以使用withHeaders
方法在傳送到應用程式之前自訂請求的標頭。你可以添加想要的任何自訂標頭。
<?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 的輔助函數。首先,你需要傳遞一個陣列給 withSession
方法來設定 Session 資料。這讓你在應用程式的測試請求發送之前,先給資料載入 Session 變得簡單:
<?php class ExampleTest extends TestCase{ public function testApplication() { $response = $this->withSession(['foo' => 'bar']) ->get('/'); } }
當然,一般使用 Session 時都是用於維護使用者狀態,例如認證使用者。 actingAs
輔助函數提供了簡單的方法來指定的使用者認證為目前使用者。例如, 我們可以使用工廠模型來產生並認證使用者:
<?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
的第二參數以指定使用者透過哪一種看守器來認證:
$this->actingAs($user, 'api')
測試JSON APIs
Laravel 也提供了幾個輔助函數來測試JSON APIs 和他們的響應。例如,json
, get
, post
, put
, patch
,和delete
可以用來傳送各種HTTP 動作。你也可以輕鬆地將資料和請求頭傳遞到這些方法中。讓我們寫一個POST
請求到/user
並斷言傳回期望的資料來開始使用他們:
<?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
方法將回應轉換為陣列並利用PHPUnit::assertArraySubset
來驗證給定的陣列存在於應用傳回的JSON 回應中。所以,如果JSON 回應中有其他屬性,測試仍舊會在給定數組存在的情況下通過:
驗證完全符合
如果你想驗證給定的陣列完全 匹配應用程式傳回的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
方法建立檔案時,你可以指定映像的寬高以及大小,從而更好的驗證測試規則:
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
除建立映像外,你也可以用create
方法創建其他類型的檔案:
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
##assertJsonMissing
#assertJsonMissing
#assertJsonMissing
assertJsonMissingExact
assertJsonMissingValidationErrors
assertJsonStructure
assertJsonValidationErrors
##asser#Location#assertJsonValidationErrors
#; #assertNotFound
assertOk
assertPlainCookie
assertRedirect
assertSee
#assertSeeInOrder
assertSeeText
assertSeeTextInOrder
assertSessionHas
assertSessionHasAllassertSessionHas
assertSessionHasAll
$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斷言回應中包含的資料與給定的JSON 資料完全匹配:
$response->assertExactJson(array $data);assertForbidden#斷言回應中有禁止狀態碼:
$response->assertForbidden();assertHeader斷言回應中有給定的套件頭:
$response->assertHeader($headerName, $value = null);assertHeaderMissing斷言回應中沒有給定的報頭:
$response->assertHeaderMissing($headerName);
斷言回應包含給定的JSON 資料:
$response->assertJson(array $data);
斷言回應JSON 中有一個數組,其中包含給定鍵的預期元素數量:
$response->assertJsonCount($count, $key = null);
斷言回應包含給定JSON 片段:
$response->assertJsonFragment(array $data);
斷言回應未包含給定的JSON 片段:
$response->assertJsonMissing(array $data);
斷言回應不包含確切的JSON 片段:
$response->assertJsonMissingExact(array $data);
斷言回應沒有給定鍵的JSON 驗證錯誤:
$response->assertJsonMissingValidationErrors($keys);
$response->assertJsonStructure(array $structure);##################
assertJsonValidationErrors
斷言回應具有給定鍵的給定JSON 驗證錯誤:
$response->assertJsonValidationErrors($keys);##assertLocation斷言回應在
Location 頭部中具有給定的URI 值:
$response->assertLocation($uri);assertNotFound斷言回應具有未找到狀態碼:
$response->assertNotFound();assertOk斷言回應有200 狀態碼:
$response->assertOk();#assertPlainCookie
##斷言回應包含給定的cookie (未加密):
$response->assertPlainCookie($cookieName, $value = null);
斷言回應會重新導向到給定的URI:
$response->assertRedirect($uri);
斷言給定的字串包含在回應中:
$response->assertSee($value);
斷言回應中有序包含了給定的字串:
$response->assertSeeInOrder(array $values);
斷言給定的字串包含在回應文字中:
$response->assertSeeText($value);
斷言給定的字串有序包含在回應文字中:
$response->assertSeeTextInOrder(array $values);
斷言session 中包含給定的資料:
$response->assertSessionHas($key, $value = null);
斷言session 中有給定值列表:
$response->assertSessionHasAll(array $data);
斷言session 中包含一個給定欄位的錯誤:
$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');
斷言session 中具有給定的錯誤:
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
斷言session 沒有錯誤:
$response->assertSessionHasNoErrors();
#assertSessionDoesntHaveErrors
#斷言session 沒有給定鍵錯誤:$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
assertSessionMissing
斷言session 中不包含給定鍵:$response->assertSessionMissing($key);
assertStatus
斷言回應中具有給定的狀態碼:
$response->assertStatus($code);##assertSuccessful斷言回應中有成功的狀態碼:
$response->assertSuccessful();#assertViewHas斷言回應視圖是一段給定的資料:
$response->assertViewHas($key, $value = null);#assertViewHasAll斷言回應視圖具有給定的資料列表:
$response->assertViewHasAll(array $data);assertViewIs斷言路由傳回給定的視圖:
$response->assertViewIs($value);assertViewMissing斷言回應視圖缺少一段綁定資料:
$response->assertViewMissing($key);Authentication AssertionsLaravel 也為你的
PHPUnit 測試提供了各種與身份驗證相關的斷言:
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); ##斷言給定的憑證無效。 |