# 前言
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。
# Introduction
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
} - Answer:
如果對 ‘/‘ 發 request, response 將會是 200, 如果不是則測試不通過
# Customizing Request Headers
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->withHeaders([
'X-Header' => 'Value',
])->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
} - Answer:
自訂 request 的 header, 然後以 POST 的方式帶著參數發到 ‘/user’ url
並斷言需以 JSON 格式回傳 ‘created’ => true, status code 為 201
Laravel Testing 中, CSRF token 會運作嗎?
不會
# Cookies
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testCookies()
{
$response = $this->withCookie('color', 'blue')->get('/');
$response = $this->withCookies([
'color' => 'blue',
'name' => 'Taylor',
])->get('/');
}
} - Answer:
建立一個 test case, 定義 cookie 為 ‘color’ => ‘blue’, 並向 ‘/‘ 發 GET request, 上面兩種定義 cookie 的方式皆可
# Debugging Responses
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function testBasicTest()
{
$response = $this->get('/');
$response->dumpHeaders();
$response->dumpSession();
$response->dump();
}
} - Answer:
對 ‘/‘ 發 GET request, 並印出 headers, session, 以及整個 response 方便 debug
# Session / Authentication
以下的 Laravel Testing example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$response = $this->withSession(['foo' => 'bar'])
->get('/');
}
} - Answer:
定義 session 載入檔案 [‘foo’ => ‘bar’], 並發送 ‘/‘ GET request
以下的 Laravel example code 的意思是?
- Example:
<?php
use App\Models\User;
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = User::factory()->create();
$response = $this->actingAs($user, 'api')
->withSession(['foo' => 'bar'])
->get('/');
}
} - Answer:
建立一個 user, 並指定由這個 user 登入, 使用 ‘api’ guard 來驗證身份 (也可不設), 並帶著 session [‘foo’ => ‘bar’], 發送 ‘/‘ GET request
# Testing JSON APIs
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
} - Answer:
使用 JSON 格式發送 POST request, 發送位址為 ‘/user’, body 為 [‘name’ => ‘Sally’]
並斷言回傳 status code 201, 以及 JSON “created” : “true”
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->postJson('/user', ['name' => 'Sally']);
$this->assertTrue($response['created']);
}
} - Answer:
使用 JSON 格式發送 POST request, 發送位址為'/user'
, body 為['name' => 'Sally']
並斷言回傳 的 JSON response 的'created'
value 為 true
# Verifying An Exact JSON Match
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
}
} - Answer:
使用 JSON 格式發送 POST request, 發送位址為'/user'
, body 為['name' => 'Sally']
並斷言 response 會是 JSON['created => true]
, 若不是則 test fail
# Verifying JSON Paths
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJsonPath('team.owner.name', 'foo');
}
} - Answer:
使用 JSON 格式發送 POST request, 發送位址為'/user'
, body 為['name' => 'Sally']
並斷言 response 需包含 status code 201, 以及在'team.owner.name'
的路徑, value 需為'foo'
# Testing File Uploads
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
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');
}
} - Answer:
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function testAvatarUpload()
{
// fake 一個 storage disk 名為 'avatars'
Storage::fake('avatars');
// fake 一個 image 名為 'avatar.jpg', 並 assign 到 $file
$file = UploadedFile::fake()->image('avatar.jpg');
// 對 '/avatar' 發起一個 JSON POST Request, 帶著 ['avatar' => $file]
$response = $this->json('POST', '/avatar', [
'avatar' => $file,
]);
// 斷言在 'avatars' 這個 storage disk 中, 有 $file 的 hash name, 若無則 test fails
Storage::disk('avatars')->assertExists($file->hashName());
// 斷言在 'avatars' 這個 storage disk 中, 沒有 'missing.jpg' 這個檔案, 若有則 test fails
Storage::disk('avatars')->assertMissing('missing.jpg');
}
}
# Fake File Customization
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
}
} - Answer:
fake 一個 image, 名為'avatar.jpg'
, 定義 width, height, 以及 size
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes, 'application/pdf');
}
} - Answer:
使用 faker 的 create method 建立一個 PDF file, 可以指定 size 以及 mimeType (optional)
# Testing Views
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testWelcomeView()
{
$view = $this->view('welcome', ['name' => 'Taylor']);
$view->assertSee('Taylor');
}
} - Answer:
test 的 view method 會 return 一個Illuminate\Testing\TestView
instance, 可帶入 view name 以及 parameters,TestView
instance 也提供了很多 assertion method:assertsee
,assertSeeInOrder
,assertSeeText
,assertSeeTextInOrder
,assertDontSee
,assertDontSeeText
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testWelcomeView()
{
$contents = (string) $this->view('welcome');
}
} - Answer:
若有需要, 也可取得 raw, rendered view 的內容
# Sharing Errors
以下的 Laravel example code 的意思是?
- Example:
<?php
class ExampleTest extends TestCase
{
public function testWelcomeView()
{
$view = $this->withViewErrors([
'name' => ['Please provide a valid name.']
])->view('form');
$view->assertSee('Please provide a valid name.');
}
} - Answer:
將模擬的 error message'name' => ['Please provide a valid name.']
待到指定的 view'form'
# Rendering Blade & Components
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$view = $this->blade(
'<x-component :name="$name" />',
['name' => 'Taylor']
);
$view->assertSee('Taylor'); - Answer:
使用 blade()
arg1 定義使用名為component
的 component, 且定義帶入的參數為 $name
arg2 定義 $name 為'Taylor'
最後斷言 $view 需可看到'Taylor'
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$view = $this->component(Profile::class, ['name' => 'Taylor']);
$view->assertSee('Taylor'); - Answer:
使用 component()
arg1 使用的 component class
arg2 定義帶入的 args key/value
最後斷言 $view 需可看到'Taylor'
# Available Assertions
# Response Assertions
# assertCookie
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertCookie($cookieName, $value = null); - Answer:
斷言 response 帶有指定 $cookie
# assertCookieExpired
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertCookieExpired($cookieName); - Answer:
斷言 response 帶有指定 $cookie, 且該 cookie 已過期
# assertCookieNotExpired
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertCookieNotExpired($cookieName); - Answer:
斷言 response 帶有指定 $cookie, 且該 cookie 還沒過期
# assertCookieMissing
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertCookieMissing($cookieName); - Answer:
斷言 response 未帶有指定 cookie
# assertCreated
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertCreated(); - Answer:
斷言 response status code 為 201
# assertDontSee
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertDontSee($value, $escaped = true); - Answer:
斷言 response 含有指定 $value string
預設會自動 escape string, 除非 arg2 為 false
# assertDontSeeText
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertDontSeeText($value, $escaped = true); - Answer:
斷言 response text 中含有指定 $value string
預設會自動 escape string, 除非 arg2 為 false
在跑此 assertion 之前, 會先把 response 的內容用 PHP functionstrip_tags
跑過
# assertExactJson
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertExactJson(array $data); - Answer:
斷言 response 中, 含有完全符合指定 $data 的 JSON data
# assertForbidden
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertForbidden(); - Answer:
斷言 response 含有 HTTP status code 403
# assertHeader
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertHeader($headerName, $value = null); - Answer:
斷言 response 含有指定的 header 以及其 value
# assertHeaderMissing
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertHeaderMissing($headerName); - Answer:
斷言 response 不含有指定 header
# assertJson
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJson(array $data, $strict = false); - Answer:
斷言 response 含有指定 JSON dataassertJson
會將 response 轉成 array, 並且使用PHPUnit::assertArraySubset
確認指定的 array 存在於 JSON response, 所以如果該 JSON response 中有其他 property, test 也會 pass 過去
# assertJsonCount
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJsonCount($count, $key = null); - Answer:
斷言 response JSON 中, 指定的 $key 為 array, 而裡頭的 item 數量跟斷言的 $count 數量相符
# assertJsonFragment
以下的 Laravel Test example code 的意思是?
- Example:
<?php
Route::get('/users', function () {
return [
'users' => [
[
'name' => 'Taylor Otwell',
],
],
];
});
$response->assertJsonFragment(['name' => 'Taylor Otwell']); - Answer:
斷言 response 中, 在某個位置有著['name' => 'Taylor Otwell'
# assertJsonMissing
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJsonMissing(array $data); - Answer:
斷言 response 中, 並無 JSON $data
假如 Response 為['a' => 1, 'b' => 2]
, 那如果 $data 為['a' => 2, 'b' => 2]
, 這樣也算 fail
# assertJsonMissingExact
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJsonMissingExact(array $data); - Answer:
斷言 response 中, 並無 JSON $data
假如 Response 為['a' => 1, 'b' => 2]
, 那如果 $data 為['a' => 2, 'b' => 2]
, 因為沒有完全符合, 這樣便不算 fail, 然而測試結果為not perform any assertion
, 不確定這樣的行為是否正常, 預期行為應為pass
# assertJsonMissingValidationErrors
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJsonMissingValidationErrors($keys); - Answer:
斷言 response 中, 並無指定 $key 的 JSON validation error
# assertJsonPath
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJsonPath($path, array $data, $strict = true); - Answer:
斷言 response 在指定的 $path 位置含有指定的 $data
見範例如下: - Demonstration:
<?php
// response
{
"user": {
"name": "Steve Schoger"
}
}
// test method
$response->assertJsonPath('user.name', 'Steve Schoger');
# assertJsonStructure
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJsonStructure(array $structure); - Answer:
斷言 response 為定義的 JSON 結構
見範例如下: - Demonstration:
<?php
// response
{
"user": {
"name": "Steve Schoger"
}
}
// test method
$response->assertJsonStructure([
'user' => [
'name',
]
]);
# assertJsonValidationErrors
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertJsonValidationErrors(array $data); - Answer:
斷言 response 需含有指定 keys 的 errors, 適用於 validator error 是以 JSON 結構回傳, 而不是置於 session 當中
# assertLocation
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertLocation($uri); - Answer:
斷言 response 的 Location header 的 value 為 $uri
# assertNoContent
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertNoContent($status = 204) - Answer:
斷言 response 需為 no content, 且 status code 為 204
# assertNotFound
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertNotFound(); - Answer:
斷言 response status code 需為 404
# assertOk
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertOk() - Answer:
斷言 response status code 需為 200
# assertPlainCookie
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertPlainCookie($cookieName, $value = null); - Answer:
斷言 response 含有指定的 unencrypted cookie
# assertRedirect
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertRedirect($uri); - Answer:
斷言 response 為 redirect 到 $uri
# assertSee
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSee($value, $escaped = true); - Answer:
斷言 response 含有 string $value, 預設會 escape 此 string, 可指定為 false
# assertSeeInOrder
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSeeInOrder(array $values, $escaped = true); - Answer:
斷言 response 中, string 的順序如 $values 的定義, 預設 escape, 可變更為 false
# assertSeeText
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSeeText($value, $escaped = true); - Answer:
斷言 response text 中有 string $value, 預設會 escape string, 可改為 false
response 內容會先經過 strip_tags 處理過, 才會到 assertion
# assertSeeTextInOrder
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSeeTextInOrder(array $values, $escaped = true); - Answer:
斷言 response text 中有 string $value, 並且照定義的順序排列, 預設會 escape string, 可改為 false
response 內容會先經過 strip_tags 處理過, 才會到 assertion
# assertSessionHas
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionHas($key, $value = null); - Answer:
斷言 session $key 含有 $value
# assertSessionHasInput
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionHasInput($key, $value = null); - Answer:
斷言 session 在 flashed input array 含有指定的 key / value
# assertSessionHasAll
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionHasAll(array $data); - Answer:
斷言 session 在 含有指定的 array [key / value]
例如 session 含有name
及status
key, 可定義如下: - Demonstration:
<?php
$response->assertSessionHasAll([
'name' => 'Taylor Otwell',
'status' => 'active',
]);
# assertSessionHasErrors
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionHasErrors(
array $keys, $format = null, $errorBag = 'default'
); - Answer:
斷言 session 中含有指定的 errors, 可以只斷言 key, 也可 key / value
這個適合用來測試會將 error 放入 session 的 route, 而不是將 error 導出 JSON response 的 route
例如, 斷言 session 中有 error message filedname
,email
(demonstration 1)
也可指定 error messagekey / value
(demonstration 2) - Demonstration1:
<?php
$response->assertSessionHasErrors(['name', 'email']); - Demonstration2:
<?php
$response->assertSessionHasErrors([
'name' => 'The given name was invalid.'
]);
# assertSessionHasErrorsIn
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null); - Answer:
斷言 session 中, messageBag $errorBag 中含有指定的 error / message$keys
, 可定義 key 以及 key / value
# assertSessionHasNoErrors
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionHasNoErrors(); - Answer:
斷言 session 中沒有 validation errors
# assertSessionDoesntHaveErrors
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default'); - Answer:
斷言 session 中沒有指定的 error key
# assertSessionMissing
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSessionMissing($key); - Answer:
斷言 session 中沒有指定的 $key
# assertStatus
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertStatus($code); - Answer:
斷言 response 的 status code 為 $code
# assertSuccessful
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertSuccessful(); - Answer:
斷言 response 的 status code 為(>= 200 and < 300)
# assertUnauthorized
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertUnauthorized(); - Answer:
斷言 response 的 status code 為 401
# assertViewHasAll
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertViewHasAll(array $data); - Answer:
<?php
// 斷言 response view 中含有指定的 keys 或是多組 key / value
$rseponse->assertViewHasAll([
'name',
'email',
]);
$rseponse->assertViewHasAll([
'name' => 'Taylor Otwell',
'email' => 'taylor@example.com,',
]);
# assertViewIs
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertViewIs($value); - Answer:
斷言 response view name 跟 $value 一樣
# assertViewMissing
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$response->assertViewMissing($key); - Answer:
斷言 response view 中沒有 $key
# Authentication Assertions
# assertAuthenticated
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$this->assertAuthenticated($guard = null); - Answer:
斷言 user is authenticated
# assertGuest
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$this->assertGuest($guard = null); - Answer:
斷言 user is not authenticated
# assertAuthenticatedAs
以下的 Laravel Test example code 的意思是?
- Example:
<?php
$this->assertAuthenticatedAs($user, $guard = null); - Answer:
斷言 $user is authenticated
留言