刻意練習,堅持
在上篇文章中,對 PHPUnit
已經有了基礎的認識後,就可以迴歸到真實的場景中,在 Laravel
框架中為應用程式編寫自動化測試程式碼。
Laravel 測試
Laravel
官方文件中,明確寫出了其對測試的良好支援,預設就支援用 PHPUnit
來做測試。這個支援可能表現在這兩個地方:
- 預設引用了
phpunit/phpunit
包 - 優雅擴充套件了
PHPUnit
瞭解 Laravel
測試結構
要在框架中編寫測試,首先得了解框架和測試程式碼的結構。
在一個 Laravel
應用根目錄下,預設存在 如下結構:
tests
目錄(編寫測試的地方)Feature
目錄(存放功能測試)Unit
目錄(存放單元測試)CreateApplication.php
檔案(用於初始化框架應用)TestCase
檔案(所有測試類需要繼承的抽象類,內部引用了CreateApplication
)
phpunit.xml
檔案(指導phpunit
執行 )。
因此,當安裝好了 PHPUnit
,並在根目錄下執行 phpunit
命令,會自動搜尋 phpunit.xml
檔案,然後根據檔案裡的配置資訊執行預設的測試。
如果沒有安裝 PHPUnit
,因為預設引用了 phpunit/phpunit
包,還可以使用 ./vendor/bin/phpunit
執行測試。
不糾結功能測試與單元測試
在上一篇文章中,就提到了不要過分糾結功能測試、單元測試這些概念的定義。但現在遇到了,就給出自己簡單的認知(不一定正確,主要是讓自己理解),以介面開發為例:
- 針對某個具體介面或多個介面組合的測試,可以稱為 “功能測試”
- 每個介面中可能呼叫多個獨立方法,針對這些方法的測試,可以理解為 “單元測試”
具體編寫測試
在有了上述的基礎後,就可以開始編寫自己的測試程式碼了,不要期望一口氣寫出多麼優雅、完善的測試程式碼,最重要的是 堅持 刻意練習,在編寫的過程中不斷調整總結自己的經驗出來。以一個簡單的儲存介面為例:
存在一個介面 xxx/article
用於新建文章,那就可以為此建立一個功能測試: php artisan make:test CreateArticleTest
,內容如下:
<?php
namespace Tests\Feature\Credits;
use Tests\TestCase;
class CreateArticleTest extends TestCase
{
// 介面URI
protected $createArticleUri = 'xxx/article';
/** @test 測試建立文章要求必填標題*/
public function create_article_require_title()
{
// 請求介面,並斷言介面響應與返回碼
$this->json('POST', $this->createArticleUri, ['title' => null])
->assertStatus(200)
->assertJson(['code' => 'xxxx']);
}
}
假設介面內部,會驗證文章是否重名,通常我們會為此編寫一個獨立方法,此時就需要建立一個單元測試: php artisan make:test ArticleTest --unit
,內容如下:
<?php
namespace Tests\Unit;
use Tests\TestCase;
class ArticleTest extends TestCase
{
/** @test 測試可以判斷文章是否重名*/
public function can_konw_title_is_repeat()
{
$articleOne = factory(Article::class)->create(['title' => '標題1']);
$articleTwo = factory(Article::class)->make(['title' => '標題1']);
$result = $articleTwo->isRepeat();
$this->assertTrue($result);
}
}
總結
上面列舉了一個非常簡單的測試,這裡並不會詳細的介紹 Laravel
框架裡測試的方法,建議閱讀官方文件,後面會列出參考連結。
要再次強調,對於開發而言,寫這些測試程式碼的難度並不高,關鍵還是要堅持寫、刻意練習、不斷總結,入門都不是問題。
在養成編寫測試程式碼的習慣後,遇到的測試場景也會越來越多,思維也會更加完善,程式碼質量隨著會更加有保障。
Laravel
網站有個文件 《TDD 構建 Laravel 論壇筆記》,是很不錯的入門指引,有條件也可以購買網站上的 L07 Laravel 教程 - Laravel TDD ,這也是很好的教程。
在入門的過程中,自己也總結了一些點:
注意直接使用
PHPUnit
與在Laravel
中使用的差異
因為Laravel
擴充套件了PHPUnit
,因此某些方法是原生PHPUnit
中不存在的,只在Laravel
中可以使用,不過這些擴充套件的內容,使用起來確實會更加優雅。使用
Laravel
資料庫事務,清理測試資料Laravel
提供了DatabaseTransaction
的Trait
,只要在測試類中引入了。就會將每個測試用例包含在事務中, 及時清除資料庫裡的測試資料。暴露異常,便於定位問題
對於介面Laravel
預設會進行異常處理,這在測試過程中是不利於除錯的,可以在測試方法中使用:// 不處理異常 $this->withoutExceptionHandling(); // 處理異常 $this->withExceptionHandling();
使用
Laravel
模型工廠快捷造資料
很多測試的執行,都需要依賴很多資料,通過Laravel
的模型工廠,可以很快捷的構造需要的資料。
參考
本作品採用《CC 協議》,轉載必須註明作者和本文連結