在 PHP 下進行單元測試,需要用到 PHP 單元測試的一個框架。這個單元測試框架隨 PEAR 即 PHP 擴展庫一起分發。所以需要首先安裝 Pear 的 PHP 單元測試擴展庫。安裝是通過網絡從有關的站點實時安裝的,所以安裝的機器必須連接到互聯網上。
一、安裝 PEAR
但從 PHP5.2 版本開始,在 Windows 下安裝 PEAR 就有一些問題,直到 PHP5.3,問題依然存在。比如,在 Zend Server Community Edition 5.0.1(包含 PHP5.3.2)下,安裝 PEAR,點擊運行 ~ZendZendServerbingo-pear.bat 批處理文件,會報錯:
“……~ZendZendServerbinPEARgo-pear.phar does not have a signature”
通過查找資料,修改 go-pear.bat 的第三條語句
%PHP_BIN% -d output_buffering=0 PEARgo-pear.phar,為
%PHP_BIN% -d phar.require_hash=0 PEARgo-pear.phar
才會開始安裝 PEAR。
修改後的 go-pear.bat 文件內容:
@ECHO OFF
set PHP_BIN=php.exe
rem %PHP_BIN% -d output_buffering=0 PEARgo-pear.phar
%PHP_BIN% -d phar.require_hash=0 PEARgo-pear.phar
pause
二、使用 PEAR 來安裝 PHPUnit:
PEAR 相當於一個管理程序,要使用 PHPUnit 的話,還必須通過 PEAR 來安裝它。注意它也是通過網絡從有關的站點實時安裝的。
依次運行命令:
pear channel-discover pear.phpunit.de
pear channel-discover pear.symfony-project.com
pear install phpunit/PHPUnit
但運行第三條命令時,報錯,提示 PEAR 版本太低,要求大於等於 1.8.1 版本。於是運行命令 pear upgrade pear 對 PEAR 進行升級(從當前的1.7.2 升級到 1.9.1)。
然後就可以安裝上 PHPUnit 了。
PEAR 有很多命令行參數,用來管理安裝的軟件包,比如:
pear upgrade pear 對 PEAR 自身進行升級
pear info pear 查看 PEAR 信息
pear list 列出已經安裝的包
pear list-all 列出所有的包
pear help PEAR 幫助信息
運行 phpunit 命令可以看到 phpunit 的有關信息。
go-pear 安裝的 PEAR 的所有的軟件包,都在 ~ZendZendServerbinpear 文件夾下,該文件夾被加入到 php.ini 的 include_path 變量中作為庫文件的搜索路徑之一。
;***** Added by go-pear
include_path=".;C:Program FilesZendZendServerbinpear;C:Program FilesZendZendServershareZendFrameworklibrary"
;*****
所以在書寫測試代碼時,語句 require_once 'PHPUnit/Framework.php' 就可以直接尋找到 PHPUnit 的庫文件。
三、使用 PHPUnit 進行單元測試
3.1 下面的例子用來測試 sizeof 函數工作的正確性:
require_once 'PHPUnit/Framework.php';
class ArrayTest extends PHPUnit_Framework_TestCase
{
public function testNewArrayIsEmpty()
{
/*Create the Array fixture*/
$fixture = array();
/* Assert that the size of the Array * fixture is 0*/
$this->assertEquals(0, sizeof($fixture));
}
public function testArrayContainsAnElement()
{
/* Create the Array fixture*/
$fixture = array();
/*Add an element to the Array * fixture*/
$fixture[] = 'Element';
/*Assert that the size of the * Array fixture is 1*/
$this->assertEquals(1, sizeof($fixture));
}
}
?>
要點:
require_once 'PHPUnit/Framework.php' 語句是必須的。
編寫的測試用例(usecase)是一個 PHP 腳本,需要在測試用例腳本中包含需要測試的代碼。
測試用例的主體必須寫在類中,類名建議和文件名保持一致,還必須是 PHPUnit_Framework_TestCase 的派生類。
每一個測試用例都是一個 public 類型的成員函數,必須以 test 開頭。
程序的輸出使用 assert* 系列函數(assertEquals、assertNotEquals、assertTrue、assertFalse、assertSame、 setExpectedException)來進行驗證(參見 http://www.phpunit.de 網站上的 PHPUnit 手冊)。
運行:
該測試用例需要在命令窗口下鍵入 phpunit ArrayTest.php 來運行,而不是用浏覽器打開它。結果如下所示:
C:Program FilesZendApache2htdocsunit_test>phpunit ArrayTest.php
PHPUnit 3.4.14 by Sebastian Bergmann.
..
Time: 1 second, Memory: 3.75Mb
OK (2 tests, 2 assertions)
其中的兩個點“..”表示,兩個測試用例全都通過。
添加一個成員函數:
public function testArrayContains2Element()
{
$fixture = array();
$fixture[] = 'Element';
$this->assertTrue(sizeof($fixture)==2);
}
然後再次測試,報告:
PHPUnit 3.4.14 by Sebastian Bergmann.
..F
Time: 0 seconds, Memory: 3.75Mb
There was 1 failure:
1) ArrayTest::testArrayContains2Element
Failed asserting that
C:Program FilesZendApache2htdocsunit_testArrayTest.php:27
FAILURES!
Tests: 3, Assertions: 3, Failures: 1.
其中的“..F”表示,兩個測試用例通過,一個失敗。並提示了出錯的位置。
PHPUnit 命令行工具輸出的指示字符:
. 當測試成功時輸出
F 當運行測試方法過程中一個斷言失敗時輸出
E 當運行測試方法過程中產生一個錯誤時輸出
S 當測試被跳過時輸出
I 當測試被標記為不完整或未實現時輸出
PHPUnit 的失敗和錯誤是不同的。失敗是指違反 PHPUnit 語法,例如 assertEquals() 調用失敗。錯誤是指異常或 PHP 錯誤。有時這種區分非常有用,因為錯誤通常比失敗容易修復。如果你得到一大串問題,最好先解決所有錯誤,然後再看還有沒有失敗。
3.2 使用數據提供者
測試方法可接受參數。這些參數將由一個數據提供者方法提供(provider())。要用到的數據提供著方法是用@dataProvider注解指定的。
數據提供者方法必須是public和static的,而且返回值必須是數組的數組或者實現了Iterator接口並且每次迭代產生一個數組的對象。對於每個數組(即集合的部分),都將以其內容為參數調用測試方法。
class DataTest extends PHPUnit_Framework_TestCase
{
public static function provider()
{
return array(
array(0, 0, 0),
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 3)
);
}
/**
* @dataProvider provider
*/
public function testAdd($a, $b, $c)
{
$this->assertEquals($c, $a + $b);
}
}
?>
*