一个函数、一个类编写完成,到底能不能正确工作?怎么测试它?PHP 单元测试是个好办法,它提供了自动化测试的方法,使敏捷开发的自动化测试成为可能。
在 PHP 下进行单元测试,需要用到 PHP 单元测试的一个框架。这个单元测试框架随 PEAR 即 PHP 扩展库一起分发。所以需要首先安装 Pear 的 PHP 单元测试扩展库。安装是通过网络从有关的站点实时安装的,所以安装的机器必须连接到互联网上。
一、安装 PEAR
但从 PHP5.2 版本开始,在 Windows 下安装 PEAR 就有一些问题,直到 PHP5.3,问题依然存在。比如,在 Zend Server Community Edition 5.0.1(包含 PHP5.3.2)下,安装 PEAR,点击运行 ~/Zend/ZendServer/bin/go-pear.bat 批处理文件,会报错:
“……~/Zend/ZendServer/bin/PEAR/go-pear.phar does not have a signature”
通过查找资料,修改 go-pear.bat 的第三条语句
%PHP_BIN% -d output_buffering=0 PEAR/go-pear.phar,为
%PHP_BIN% -d phar.require_hash=0 PEAR/go-pear.phar
才会开始安装 PEAR。
修改后的 go-pear.bat 文件内容:
@ECHO OFF
set PHP_BIN=php.exe
rem %PHP_BIN% -d output_buffering=0 PEAR/go-pear.phar
%PHP_BIN% -d phar.require_hash=0 PEAR/go-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 的所有的软件包,都在 ~/Zend/ZendServer/bin/pear 文件夹下,该文件夹被加入到 php.ini 的 include_path 变量中作为库文件的搜索路径之一。
;***** Added by go-pear
include_path=".;C:/Program Files/Zend/ZendServer/bin/pear;C:/Program Files/Zend/ZendServer/share/ZendFramework/library"
;*****
所以在书写测试代码时,语句 require_once 'PHPUnit/Framework.php' 就可以直接寻找到 PHPUnit 的库文件。
三、使用 PHPUnit 进行单元测试
3.1 下面的例子用来测试 sizeof 函数工作的正确性:
<?php
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 Files/Zend/Apache2/htdocs/unit_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 <boolean:false> is true.
C:/Program Files/Zend/Apache2/htdocs/unit_test/ArrayTest.php:27
FAILURES!
Tests: 3, Assertions: 3, Failures: 1.
其中的“..F”表示,两个测试用例通过,一个失败。并提示了出错的位置。
PHPUnit 命令行工具输出的指示字符:
. 当测试成功时输出
F 当运行测试方法