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
2
3
4
5
6
7
8
9
10
$ sudo apt-get remove phpunit    // 應該是前面有先用 apt-get install 裝了才需要
$ sudo pear upgrade pear // pear 只要裝了 php 就有
$ sudo pear channel-discover pear.phpunit.de
$ sudo pear channel-discover pear.symfony-project.com
$ sudo pear channel-discover components.ez.no
$ sudo pear update-channels
$ sudo pear upgrade-all
$ sudo pear install -alldeps phpunit/PHPUnit
$ sudo pear uninstall phpunit/PHPUnit
$ sudo pear install phpunit/PHPUnit

最後兩個指令看起來很好笑,好像是 pear 的 script 有問題。用倒數第三行裝完之後,又會說找不到 PHP_CodeCoverage_Filter::getInstance(),後來做這兩行就動了。

失敗的安裝

不能直接用

1
$ sudo apt-get install phpunit

不然 run 的時候會該找不到 PHP Code Coverage。

Run test

run all tests

1
2
$ phpunit
$ phpunit --stderr

PHPUnit 在一些系統上會有 header already sent 的錯誤,加 --stderr 可以避免 PHPUnit 把這視為測試錯誤。

執行單一測試,指定某測試檔做測試。

1
$ phpunit --stderr <test file path>

Basic conventions

  1. class “Class” 的 test 放在 class “ClassTest”
  2. ClassTest 要繼承 PHPUnit_Framework_TestCase
  3. test 為 public method,method name 為 test*
  4. 在 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
2
object/
MyStack.php

這是 test directory:

1
2
tests/
MyStackTest.php

PHPUnit 會在 test dir(上例的 tests/)底下找 *Test.php 來做測試。

執行 test suite

1
$ phpunit --stderr <test dir path>

寫 test 就是…

  1. 生一些 testcase(input 及預期的 output)
  2. 在 test method 裡 call 要測的 function,把 test case 的 input 當作 arg 丟進去。
  3. 用 asseert function 判斷 function 的 output 是否符合預期。

Ref