Laravel - Testing - HTTP Tests (官方文件原子化翻譯筆記)

# 前言

學習一個框架, 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 function strip_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 data
    assertJson 會將 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 含有 namestatus 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 filed name, email (demonstration 1)
    也可指定 error message key / 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
資料結構 - Tree - 不同類型的 Binary Tree Laravel - Testing - Getting Started (官方文件原子化翻譯)

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×