###### 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.
```