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