iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 9
2
Software Development

如何一步步實踐TDD (測試驅動開發)系列 第 9

測試覆蓋率 與 PHPUnit 設定檔

今天回到我們的測試框架,關於測試的覆蓋率,之前提過 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/

phpunit-coverage-text

出現覆蓋率的整理了!
有 2 個類別、3 個函式、總共9 行程式有被測試覆蓋,看到了令人振奮的 100% 覆蓋率。

--colors

純粹只是想讓純文字看起來繽紛一點,不同的覆蓋率會用不同顏色,可以再加入這個參數:

$ ./vendor/bin/phpunit tests/ --coverage-text --whitelist src/ --colors

phpunit-coverage-text-color

(話說疑惑時區竟然是用 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就可以看到圖形介面的報告。
phpunit-coverage-html-1

如果點進檔案,還可以看到每一行程式碼是否被測試的情況。

phpunit-coverage-html-2

phpunit.xml 設定檔

不過其實每次都要打那麼長的 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% 覆蓋率,卻可能寫出一些根本沒必要的測試,不符合實際會發生的情況,同時也並不是 100% 就代表整個系統都沒有錯誤,是個對於覆蓋率的迷思。


參考資料

  1. PHPUnit Manual - 3. The Command-Line Test Runner
  2. PHPUnit Manual - 9. Code Coverage Analysis
  3. PHPUnit Manual - Appendix 3. The XML Configuration File

附註

  1. PHPUnit 中還有非常多的設定選項,有興趣可以參考官方文件。

上一篇
自動化測試的層級
下一篇
如何在一個環境開始 TDD
系列文
如何一步步實踐TDD (測試驅動開發)30

尚未有邦友留言

立即登入留言