上一篇做了一些更動,包含 貼文路由需驗證 及 Post
關聯到 User
。
但不小心破壞到原本寫好的程式了,讓我們來看看是什麼問題。
5d
。首先來查看,執行 PHPUnit 時跳出了什麼錯誤訊息。
Post (Tests\Feature\Post)
✔ All post
✔ Insert post
✘ Insert post by get route
┐
├ Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: posts.user_id (SQL: insert into "posts" ("post_text", "user_id", "updated_at", "created_at") values (It's a new post., ?, 2019-10-08 13:18:19, 2019-10-08 13:18:19))
可以知道是 Insert post by get route
這個測試,並且發現 NOT NULL constraint failed: posts.user_id
,判斷是因為新增資料時,Not null 的欄位沒有資料。
有時候出現錯誤,我們要修正的是 Bug 的來源。
但這裡的情況是,我們程式的邏輯已經改變:新增貼文需要已登入,並抓取 user.id 放到 posts 的 user_id 中。
原本用來貼文的 GET 路由,我們已經不再需要它,因此我們直接刪掉那段程式與測試就可以了 [1]。
// routes/web.php
// Route::get('/post/insert', 'PostController@insertPost');
// tests/Feature/PostTest.php
// public function testInsertPostByGetRoute()
// {
// ...
// }
Post 方法的新增貼文,我們要繼續留著用,因此來修改測試。
類似的情況,POST 路由的控制器其實已經是寫好的程式碼,因此比較像是重構。
public function testInsertPostByPostRoute()
{
$users = factory(User::class, 2)->create();
$second_user = $users[1];
$text = "It's a new post.";
$this->actingAs($second_user)
->post('/post',[
'post_text' => $text
]);
$this->assertDatabaseHas('posts', [
'post_text' => $text,
'user_id' => $second_user->id
]);
$response = $this->get('/post');
$response->assertSee($text);
}
( $ git checkout 5d
)
相對於 Dusk 的 LoginAs(),Laravel 支援 actingAs()
來登入特定使用者。
我們目前有兩種測試:PHPUnit 與 Dusk:
$ php artisan dusk
PHPUnit 8.3.5 by Sebastian Bergmann and contributors.
.... 4 / 4 (100%)
Time: 6.86 seconds, Memory: 26.00 MB
OK (4 tests, 5 assertions)
$ ./vendor/bin/phpunit
PHPUnit 8.3.5 by Sebastian Bergmann and contributors.
.... 4 / 4 (100%)
Time: 535 ms, Memory: 26.00 MB
OK (4 tests, 7 assertions)
終於回到了測試全部通過的狀態,感覺不錯。
再次介紹一下 Regression Test,我們曾在 TDD 的理由 中提到過。
它的用途是當我們有了一個新版本的程式,或甚至每一次對程式碼的任何更動後,我們去執行一次自動化測試,確保原有的程式並沒有被破壞。
由於自動化測試很快就能執行完,幾乎不需要等待,讓開發者更願意隨時進行 regression test。
而上一篇的實作後,能夠那麼快發現有 Bug,以及在本篇中找到是從哪裡發生的,也就是仰賴了自動化測試與 regression test,我們有很高的機會能透過它們抓到剛出現的錯誤。