前言
本文為《現代 PHP》一書的學習筆記。
環境
- Windows 10
- Wnmp 3.1.0
測試
許多 PHP 開發者將測試視為不必要且浪費時間的行為,而且現存太多的測試工具,有著不易上手的學習曲線。但其實測試是一個會發生在應用程式開發流程的開始、中途和結束的程序。
為何要做測試
測試可以幫助開發者在第一時間就運作良好的程式,不需要在未來浪費無數小時來為程式除錯並重構。
何時要做測試
測試是一個在開發前、開發中、開發後都存在的議題,敷衍地建立幾個測試並且通過它,這是錯誤的行為。
開發前:安裝並部署測試工具。
開發中:建立應用程式中的每個部分時,都撰寫測試並執行測試。
開發後:持續性地修正並改良測試,就像應用程式本身一樣。
測試什麼
獨立地測試應用程式中最小的區塊,如每個類別、方法和函式,以確保他們如預期執行,這種測試稱為「單元測試」。
但測試區塊並不能保證整個應用程式都能如期運作,因此還需要利用自動化的工具測試應用程式高層級的行為,這種測試稱為「功能測試」。
如何測試
PHP 開發者使用了幾種熱門的方式進行測試,他們之間並不互斥。
單元測試
單元測試是最熱門的,現在標準的 PHP 單元測試框架為由 Sebastian Bergmann 所撰寫的 PHPUnit。
測試驅動開發(TDD)
測試驅動開發(Test-driven development)是在撰寫程式碼之前先撰寫測試,這些測試會故意失敗,因為它描述了應用程式應當擁有的行為。
TDD 不停重複「撰寫測試並建立功能」的這個過程,直到應用程式完成為止。
行為驅動開發(BDD)
行為驅動開發(Behavior-driven development)有兩種形式:SpecBDD 和 StoryBDD。
BDD 使用流暢的人性化語言來描述應用程式的實作層面,SpecBDD 測試以開發者的角度組合事情,而 StoryBDD 以專案管理者的角度組合事情,他們經常被一起使用。
PHPUnit
PHPUnit 測試會集合成測試案例,測試案例會集合成測試程序,PHPUnit 會使用測試執行器來進行測試。
每個案例都包含了名稱以 test 為前綴的公開方法,這些方法是獨立的測試,用來測試特別的情況是否如預期執行。
一個測試類別通常以
Test結尾。
初始的 PHPUnit 測試執行器是命令列執行器,可以在終端機使用 phpunit 指令來觸發。
目錄架構
範例的目錄架構如下:
1 | |- src/ |
src目錄包含 PHP 專案的原始碼。tests目錄包含 PHP 專案的 PHPUnit 測試,其中的bootstrap.php檔在單元測試執行前,會由 PHPUnit 所匯入。composer.json列出 Composer 所管理的相依性元件。phpunit.xml提供 PHPUnit 測試執行器的設定細節。.travis.yml提供 Travis CI 持續測試網頁服務所需要的設定細節。
啟用 Xdebug
Xdebug 剖析器可以用來產生有用的程式碼覆蓋率資訊。
如果是在 Wnmp 的環境,打開 php.ini 檔並取消以下註解以啟用 Xdebug PHP 擴充。
1 | ;zend_extension=php_xdebug.dll |
安裝 PHPUnit
Composer 是安裝 PHPUnit 測試框架最方便的方式之一。
1 | composer require --dev phpunit/phpunit |
配置 PHPUnit
在專案的 phpunit.xml 檔中配置 PHPUnit。
1 |
|
<phpunit>根元素的屬性是 PHPUnit 測試執行器的設定,最重要的設定是bootstrap設定,它指明在 PHPUnit 測試執行前,會被匯入的 PHP 檔案路徑。<testsuites>元素定義tests資料夾中,以Test.php結尾的檔案將被 PHPUnit 執行。<filter>元素列出所有包含在程式碼覆蓋率檢測中的目錄。<whitelist>元素告訴 PHPUnit 只要針對src目錄進行程式碼覆蓋率檢測。
實作
假想一個 Whovian 類別作為測試範例。
範例 10-1:Whovian 類別
1 | class Whovian |
每個測試案例都需要繼承 PHPUnit_Framework_TestCase 類別。
範例 10-2:WhovianTest 測試案例
1 |
|
assertAttributeEquals()方法斷言預期的値與指定物件的屬性的値相同。assertEquals()方法斷言預期的値與結果的値相同。
執行測試
打開終端機,進入專案的最上層目錄,使用以下指令啟動 PHPUnit 測試執行器。
1 | vendor/bin/phpunit -c phpunit.xml |
-c或--configuration選項可以使用不同的設定檔。
程式碼覆蓋率
PHPUnit 的程式碼覆蓋率報表,可以觀看哪些程式碼被測試(或未被測試)。
使用以下指令生成報表。
1 | vendor/bin/phpunit -c phpunit.xml --coverage-html coverage |
--coverage-html的値代表存放報表的資料夾路徑。
接著,在 http://localhost/php/modern-php/10-testing/coverage/ 可以查看報表。
通常 100% 的覆蓋率是不切實際的,覆蓋率多寡的程度根據每個專案而有所不同。
Travic CI
測試應當自動化執行,Travic CI 是很好的持續測試網頁服務,因為它可以原生地和 GitHub 儲存庫結合。
前往 Travic CI,以 GitHub 帳戶登入,選擇要測試的儲存庫。
範例的 .travis.yml 檔如下:
1 | language: php |
language是應用程式所使用的語言。php是 Travic CI 要測試應用程式的 PHP 版本。before_script是在 Travic CI 要測試應用程式之前會執行的指令。script是在 Travic CI 要測試應用程式時執行的指令。notification是通知的相關設定。
執行
每次提交新的程式碼到 GitHub 儲存庫時,Travic CI 會自動執行應用程式測試,並將測試結果以電子郵件通知。