PHPUnit
PHP 的 Unit Test Framework。
Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead.
~ Martin Fowler
test 要是 independent。一個 test 的 result 不能 depend 其他 test 的 result。
Install on Ubuntu 12.04
1 | $ sudo apt-get remove phpunit // 應該是前面有先用 apt-get install 裝了才需要 |
最後兩個指令看起來很好笑,好像是 pear 的 script 有問題。用倒數第三行裝完之後,又會說找不到 PHP_CodeCoverage_Filter::getInstance()
,後來做這兩行就動了。
失敗的安裝
不能直接用
1 | $ sudo apt-get install phpunit |
不然 run 的時候會該找不到 PHP Code Coverage。
Run test
run all tests
1 | $ phpunit |
PHPUnit 在一些系統上會有 header already sent 的錯誤,加 --stderr
可以避免 PHPUnit 把這視為測試錯誤。
執行單一測試,指定某測試檔做測試。
1 | $ phpunit --stderr <test file path> |
Basic conventions
- class “Class” 的 test 放在 class “ClassTest”
- ClassTest 要繼承 PHPUnit_Framework_TestCase
- test 為 public method,method name 為 test*
- 在 test 中,用 assert*() function check value 是否符合預期
failure vs error
failure 是 assertion function fail(要測試的 function 的 output 不符合預期)。以 F 代表。
error 是出現 unexpected exception 或 PHP error。以 E 代表。
setUp() & tearDown()
為了讓測試是正確且獨立的,要保持執行 test 時環境是乾淨的。在每次執行一個 test method 前會 call setUp()
建立 test 所需要的 object、變數等等。run 完 test method 後會 call tearDown()
清東西。
通常只需 implement tearDown()
,用來 close file、socket 等。
用 file system 組合 test suite
可以用 file system 的 directory structure 達到組合出一個 test suite 的目的。這也是最簡單的方式。:)
建立一 test dir 並建立跟 project dir 中一樣的 directory structure。把 test case source file(就是 test method 的 source code)以相應 project source file 的位置放進去。PHPUnit 會自動 traverse test dir 做 test。
舉例說明:
這是 project directory:
1 | object/ |
這是 test directory:
1 | tests/ |
PHPUnit 會在 test dir(上例的 tests/)底下找 *Test.php 來做測試。
執行 test suite
1 | $ phpunit --stderr <test dir path> |
寫 test 就是…
- 生一些 testcase(input 及預期的 output)
- 在 test method 裡 call 要測的 function,把 test case 的 input 當作 arg 丟進去。
- 用 asseert function 判斷 function 的 output 是否符合預期。