###### tags: `Laravel` # Laravel Testing [Laravel – Unit Test 單元測試教學](http://bit.ly/cary-test) # 環境 - 建立測試用的資料庫 - 可以直接修改 .env 指定的 DATABASE 名即可 - 建立 Migration - 建立 Model # Factory 建立假資料工廠 - php artisan make:factory PostFactory --model=Post - --model=Post 他會自動幫你加 use 該 Model - 建立的檔案位於 database/factories 之下 ```php $factory->define(Post::class, function (Faker $faker) { return [ // 回傳 $faker 產生的字、文章 'title' => $faker->word, 'content' => $faker->paragraph ]; }); ``` # Unit Test (tests/Unit) - php artisan make:test PostTest --unit - --unit 將檔案放在 Unit 夾,預設為 Feature 夾 * 小心使用 use RefreshDatabase 不可用於正式環境 ```php class PostTest extends TestCase { // 可以重整資料表,避免測試資料不斷累積。注意這會刪除所有資料,不要用在正式環境 use RefreshDatabase; public function testExample() { // 建立5筆資料 (記得 Import Model) factory(Post::class, 5)->create(); // 取得所有資料 $posts = Post::all(); // 判斷資料筆數: assertCount 首個變數為想要的值,後方為要檢查的資料 $this->assertCount(5, $posts); } } ``` # assert Functions 用來判斷資料是否正確 - [官方文件](http://bit.ly/laravel-assertFunc) # Faker 假資料庫參數 - [官方文件](http://bit.ly/php-faker-type) # 運行測試指令 vendor\bin\phpunit - 他會去運行所有 tests 資料夾下的 *.php - 寫於 tests 資料夾下的 Function,會被該指令執行 ```php (Windows) vendor\bin\phpunit (Linux) vendor/bin/phpunit ``` # 僅測試特定 Function - [stack overflow 看解2](http://bit.ly/laravel-test-one) - Function 上方註解 可將該 Function 註冊在該 group - 使用 vendor\bin\phpunit --group test 運行該組成員 ```php /** * @group test * @group fail */ public function testBasicTest() { $this->assertTrue(true); } ``` # Git Bash 可能會出錯 - PHPStorm 修改 Terminal 回 cmd.exe - Tool/Terminal/shellPath "C:\Program Files\Git\bin\sh.exe"--login-i - 修改成 cmd.exe 即可 # API Test (tests/Feature) * 注意要測試的路由,請確認是否在 Route(web.php) 有編寫並且使用方法一致 * assertExactJson 一定要檢查所有欄位 * assertJson 可只檢查其中幾項 (較常用) ```php class ProductTest extends TestCase { public function testExample () { $pid = 100; $response = $this ->withHeaders(['X-Header' => 'Value',]) ->json('GET', 'products', [ 'id' => $pid, ]); $response ->assertStatus(200) // 檢查狀態碼 201 為 Created ->assertJson([ 'id' => $pid, 'title' => true // 檢測存在(較常用) // 'title' => 'productTitle', // 完全相同才行 ]); // 若要為 Response 除錯,可以選用添加 $response->dumpHeaders(); // 查看丟過來的 Header $response->dump(); // 查看丟過來的 Body } } ``` # 測試錯誤訊息 彙整 - 紅: Failed - 橘: OK, but incomplete, skipped, or risky tests! - 綠: OK ```php // RED // Failed asserting that actual size 10 matches expected size 5. // 代表資料庫有10筆,但你檢測的要求為 5 筆 // 此引用可以重整資料表,避免測試資料不斷累積。注意這會刪除所有資料,不要用在正式環境 use RefreshDatabase; ``` ```php // OK, but incomplete, skipped, or risky tests! // Function 內必須有做事,否則會出現此訊息 ! public function testBasicTest() { // 空 Function 可用 如下 檢查後面的值是否為 true,即可順利運行 // $this->assertTrue(true); } ``` # 注意 test 的路徑 - Tests\Feature\ExampleTest 檔名下的 testBasicTest Function - 希望收到 200 (OK) 但 404 (找不到),可能是 Route 那邊沒有設定 '/' - Expected status code 200 but received 404. ```php 1) Tests\Feature\ExampleTest::testBasicTest Expected status code 200 but received 404. Failed asserting that false is true. ```