今天回到我們的測試框架,關於測試的覆蓋率,之前提過 TDD 能夠帶來高覆蓋率,代表我們的產品程式幾乎都有被自動化測試過,因此提高對於產品執行無誤的信心。
讓我們來說明 PHPUnit 提供覆蓋率報告的使用方法,將範例三來加入覆蓋率的計算。
先回想 PHPUnit 的基本執行方式:
$ ./vendor/bin/phpunit tests/
如果想要看 phpunit command line 有哪些選項,可以在後面加上 -h / --help,預設若沒輸入任何選項,也會印出說明。
$ ./vendor/bin/phpunit -h
--coverage-text
印出的說明文件馬上就看到了關於覆蓋率的用法Code Coverage Options
,來用用看其中的--coverage-text
。
$ ./vendor/bin/phpunit tests/ --coverage-text
Error: No whitelist is configured, no code coverage will be generated.
欸不對啊,不是應該跳出覆蓋率的整理嗎,怎麼跳出了錯誤訊息。
在 PHPUnit 中計算覆蓋率,需要設定白名單whitelist
,它才會知道哪些檔案是需要加入計算的,否則資料夾內有很多檔案跟產品程式無關的。
把指令再加入白名單 --whitelist
的設定,後面接著路徑。
$ ./vendor/bin/phpunit tests/ --coverage-text --whitelist src/
出現覆蓋率的整理了!
有 2 個類別、3 個函式、總共9 行程式有被測試覆蓋,看到了令人振奮的 100% 覆蓋率。
--colors
純粹只是想讓純文字看起來繽紛一點,不同的覆蓋率會用不同顏色,可以再加入這個參數:
$ ./vendor/bin/phpunit tests/ --coverage-text --whitelist src/ --colors
(話說疑惑時區竟然是用 GMT+2)
--coverage-html
覆蓋率的輸出形式有好幾種,來看看輸出成 HTML 網頁的形式,換成--coverage-html
,後面加上輸出檔案的路徑。
$ ./vendor/bin/phpunit tests/ --coverage-html report/ --whitelist src/
這次覆蓋率報告就沒有直接印在 Terminal 上,而是僅印出以下的文字,報告輸出到我們給的report/
路徑。
Generating code coverage report in HTML format ... done [46 ms]
用瀏覽器開啟report/index.html
就可以看到圖形介面的報告。
如果點進檔案,還可以看到每一行程式碼是否被測試的情況。
不過其實每次都要打那麼長的 Command line,其實也是蠻不容易記住的。
我們可以寫一個設定檔 phpunit.xml
讓 PHPUnit 讀取設定,讓指令更簡便 [1]。
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true">
<testsuites>
<testsuite name="tests">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist >
<directory>./src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
</logging>
</phpunit>
( $ git checkout 3d
)
<phpunit>
所有的設定都要包在這個 tag 底下,部分設定是直接放在這個 tag 裡,像是這邊用到的 colors="true"
。
<testsuites>
與 <testsuite>
<testsuites>
可以包著複數個<testsuite>
,代表有哪些是我們要執行的測試資料夾。
name
是必要的自定義名稱,僅在測試報告上顯示,<directory>
包起來的值./tests/
,則是實際的測試檔案路徑。
<filter>
與 <whitelist>
<filter>
裡的<whitelist>
放著要計算覆蓋率的產品程式碼路徑及其他設定,同樣路徑要被<directory>
包起來。
<logging>
與 <log>
最後是設定要輸出的方式 (e.g. 輸出成 HTML 或直接印到 terminal 上),<logging>
中可以有多個<log>
,每一個<log>
是一種輸出,設定多種的話,就全部都會處理,更多的 Logging 設定可參考官方文件。
最初的基本指令,PHPUnit 就會自動抓取設定檔,不需要再打那麼多參數了,連原本的測試檔路徑tests/
也不用了。
$ ./vendor/bin/phpunit
最後提一下關於目前的 100% 覆蓋率,雖然 100% 這件事聽起來好像很厲害,但實際上複雜的系統幾乎是不可能達到 100% 的。
我們的確需要追求高覆蓋率,讓更多程式碼都有經過自動化測試,然而一味追趕 100% 覆蓋率,卻可能寫出一些根本沒必要的測試,不符合實際會發生的情況,同時也並不是 100% 就代表整個系統都沒有錯誤,是個對於覆蓋率的迷思。