在上篇日记中我介绍了写一个基本的测试类的方法,今天在基本测试类的基础上,再来介绍测试方法的进阶功能。
测试方法间的依赖关系
PHPUnit可以实现测试方法的依赖关系,也就是说,一个测试方法的参数的内容和是否会运行依赖于另外一个测试方法结果,依赖关系通过注释@depends来定义.这个特性一般用于检查代码的逻辑过程,一个逻辑的执行前提是另外一个逻辑的执行结果.下面来看代码例子:
在上面的测试类StackTest中,定义了2个依赖测试方法,testPush依赖于testEmpty, testPop依赖于testPush.那么在测试运行时,testEmpty中的断言执行完毕也没有出现问题时,方法中的return语句会将 $stack传给依赖于它的testPush,作为testPush的参数传入到testPush中,testPush执行完毕之后,也会将$stack传给依赖于它的testPop,只要断言检查没有出现异常,那么PHPUnit就会根据依赖关系依次执行依赖的测试方法,直到依赖关系结束为止.
另外,为了方便快速的确定问题的所在,如果某个测试方法依赖的方法测试没有功过,那么PHPUnit会自动跳过后面所有的依赖测试,下面看代码例子:
testOne中断言为True,但是传入的是false,testOne的测试不会通过,那么依赖于testOne的testTwo也会被自动跳过.
数据提供者(Data Providers)
在前面的例子我们可以看到:测试方法是可以有参数的,在依赖关系中参数的值是它依赖的测试方法传入.那么某个测试方法没有依赖的方法,我们怎么给它传入参数做测试呢?PHPUnit给我们提供了数据提供者方法来为测试方法传入数据.
数据提供者方法需要定义在当前的测试类中,在测试方法的注释中使用@dataProvider标签标注给它提供数据的方法名,定义之后PHPUnit会自动的将数据提供者方法返回的数据依次传入到测试方法中测试.
数据提供者相当于都取大量数据测试时的封装
下面我们来看代码:
在上面的代码中,方法add_provider就是测试方法testAdd的数据提供者方法,它会依次给testAdd传入4组测试数据,testAdd会测试4次.
在这里要注意的是数据提供者方法返回数据的格式: 需要返回的是2维数组,第二维数组值的位置,对应测试方法参数的位置,参数个数和数组长度要相等,否则PHPUnit会报错,下面是个用于理解的简单的例子:
return array(
array(参数1,参数2,参数3,参数4,参数N),
array(参数1,参数2,参数3,参数4,参数N),
);
除了数组外,PHPUnit还支持数据提供者方法返回迭代器对象,迭代器的介绍估计大部分PHPer比较陌生,详细的介绍可以去http://php.net/manual/en/class.iterator.php 察看
,下面我们来看代码(点击图片放大察看):
和前一个例子实现的测试内容相同,但是数据提供者返回的是一个迭代器对象而不是是数组
数据提供者方法和依赖关系的限制
当一个测试方法依赖于另外一个使用data providers测试方法时,这个测试方法将会在它依赖的方法至少测试成功一次后运行,同时使用data providers的测试方法的执行的结果不能传入一个依赖它的测试方法中.这个解释来自官方的文档,理解起来可能有点难,我们通过代码来描述下这个限制:
上面代码例子中:
情况1: add_provider提供的数据至少有一对数据相等
testC会执行一次, 因为testC是依赖于testB的, 但是testB使用了数据提供者方法,那么testC中是无法收到testB return的值的
情况2: add_provider提供的数据没有一对数据相等
testC永远不会执行
测试异常
有时候我们需要测试某些情况下代码是否按照要求抛出了相关的异常.在PHPUnit中,我们有3种方式来检查异常是否抛出.
方法一: 注释法, 用@expectedException 标定期待的异常
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
}
方法二: 设定法,使用 $this->setExpectedException 设定期待的异常
public function testException()
{
$this->setExpectedException('InvalidArgumentException');
}
方法三: try catch + fail法
public function testException() {
try {
// 这里写上会引发异常的代码
} catch (InvalidArgumentException $expected) {
// 抓到异常测试通过
return ;
}
// 没抓到异常就算失败
$this->fail('An expected exception has not been raised.' );
}
测试PHP错误
有时候我们的代码在运行时会出现php错误,如整除0,文件不存在等等.在PHPUnit中,它会自动把错误转换为异常PHPUnit_Framework_Error并抛出,我们只需要在测试方法中设定抓取这个异常即可:
/**
* @expectedException PHPUnit_Framework_Error // 期待PHPUnit_Framework_Error的异常
*/
public function testFailingInclude()
{
// include一个不存在的文件,就会抛出一个PHPUnit_Framework_Error的异常
include 'not_existing_file.php';
}
本篇日记完结,下篇讲详细的介绍PHPUnit测试的核心:断言