PHPUnit是一个轻量级的PHP测试框架。它是在PHP5下面对JUnit3系列版本的完整移植,是xUnit测试框架家族的一员(它们都基于模式先锋Kent Beck的设计)
针对类 Class 的测试写在类 ClassTest中。
ClassTest(通常)继承自 PHPUnit_Framework_TestCase。
测试都是命名为 test* 的公用方法。
也可以在方法的文档注释块(docblock)中使用 @test 标注将其标记为测试方法。
在测试方法内,类似于 assertEquals()这样的断言方法用来对实际值与预期值的匹配做出断言。
例:用 PHPUnit 测试数组操作
class StackTest extends PHPUnit_Framework_TestCase
{
public function testPushAndPop()
{
$stack = array();
$this->assertEquals(0, count($stack));
array_push($stack, 'foo');
$this->assertEquals('foo', $stack[count($stack)-1]);
$this->assertEquals(1, count($stack));
$this->assertEquals('foo', array_pop($stack));
$this->assertEquals(0, count($stack));
}
/**
* 定义test标签声明改方法是测试方法
* @test
*/
public function indexEquals()
{
$stack = array(1,2,3,4);
$this->assertEquals(2,$stack[0]); //失败
}
}
?>
- 通俗的讲,单元测试就是在测试用例类中,定义一系列的测试方法,在方法中使用断言(assert)来测试你程序中的相关函数、类、接口、过程的执行结果是否和你预期的是一样的,
- 如果某个部分的执行结果没有与你期待的结果相同,PHPUnit就会向你报告问题,你也可以方便的根据报告确认和修复程序中的Bug。针对你的程序写好详细的完整单元测试,你就不用每次完成一个新功能后逐个的测试你软件的所有功能,而且在程序发布之前,你至少可以通过测试消灭大部分的内部逻辑Bug和缺陷。
- 同样,你在之后的维护开发中,如果在某个功能的修改中不小心改坏了与其相关连的其他模块,那么先前完善的单元测试也会向你报告出相关的问题让你及时发现和修复问题。
例:用 @depends 标注来表达依赖关系
class StackTest extends PHPUnit_Framework_TestCase
{
public function testEmpty()
{
$stack = array();
$this->assertEmpty($stack);
return $stack;
}
/**
* @depends testEmpty
*/
public function testPush(array $stack)
{
array_push($stack, 'foo');
$this->assertEquals('foo', $stack[count($stack)-1]);
$this->assertNotEmpty($stack);
return $stack;
}
/**
* @depends testPush
*/
public function testPop(array $stack)
{
$this->assertEquals('foo', array_pop($stack));
$this->assertEmpty($stack);
}
}
?>
拥有多个 @depends 标注的测试,其第一个参数是第一个生产者提供的基境,第二个参数是第二个生产者提供的基境,以此类推
class MultipleDependenciesTest extends PHPUnit_Framework_TestCase
{
public function testProducerFirst()
{
$this->assertTrue(true);
return 'first';
}
public function testProducerSecond()
{
$this->assertTrue(true);
return 'second';
}
/** 多重依赖
* @depends testProducerFirst
* @depends testProducerSecond
*/
public function testConsumer()
{
$this->assertEquals(
array('first', 'second'),
func_get_args()
);
}
}
?>
例:使用返回数组的数组的数据供给器
class DataTest extends PHPUnit_Framework_TestCase
{
/**
*@dataProvider additionProvider
*/
public function testAdd($a, $b, $expected)
{
$this->assertEquals($expected, $a + $b);
}
public function additionProvider()
{
return array(
array(0, 0, 0),
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 3)
);
}
}
?>
例:
class DependencyAndDataProviderComboTest extends PHPUnit_Framework_TestCase
{
public function provider()
{
return array(
array('provider1'),
array('provider2'));
}
public function testProducerFirst()
{
$this->assertTrue(true);
return 'first';
}
public function testProducerSecond()
{
$this->assertTrue(true);
return 'second';
}
/**
* @depends testProducerFirst
* @depends testProducerSecond
* @dataProvider provider
*/
public function testConsumer()
{
$this->assertEquals(
array('provider1', 'first', 'second'),
func_get_args()
);
}
}
?>
class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testException()
{
$this->expectException(InvalidArgumentException::class);
}
}
?>
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
}
}
?>
PHPUnit 支持共享建立基境的代码。在运行某个测试方法前,会调用一个名叫 setUp() 的模板方法。setUp() 是创建测试所用对象的地方。当测试方法运行结束后,不管是成功还是失败,都会调用另外一个名叫 tearDown() 的模板方法。tearDown() 是清理测试所用对象的地方。
在编写测试用例的时候可能最费时间的就是编写那些将程序设置到使用状态和测试完毕之后将其再设置回初始状态的代码了。PHPUnit给我们提供了setUp和tearDown这两个方法来解决这个问题。
测试类的每个测试方法都会运行一次 setUp() 和 tearDown() 模板方法(同时,每个测试方法都是在一个全新的测试类实例上运行的)。
setUpBeforeClass() 与 tearDownAfterClass() 模板方法将分别在测试用例类的第一个测试运行之前和测试用例类的最后一个测试运行之后调用。