PHP单元测试利器 PHPUNIT深入用法(三)第1/2页

2015-01-24信息快讯网

在本系列文章的前两篇中PHP单元测试利器:PHPUNIT初探和PHP单元测试利器:PHPUNIT深入用法(二)中,分别介绍了phpunit的基本用法和phpunit中的一些重要用法。

在本文中,笔者将为大家介绍phpunit中的两个高级概念和用法,尽管它不一定在你的日常单元测试中都用到,但理解和学会它们的用法对学习phpunit还是十分重要的。

  Phpunit中的Annotations

  如果有其他编程语言经验的开发者,应该对Annotations(注解)不陌生,其实在phpunit中,一个简单的如下面的一段注释也可以认为是Annotations:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网<?php
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
class MyTestClass extends PHPUnit_Framework_TestCase
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Testing the answer to “do you love unit tests?”
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public function testDoYouLoveUnitTests()
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$love = true;
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$this->assertTrue($love);
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
?>

   可以看到,其实一段以/** **/为标记的文字,就可以认为是一种Annotations,但Annotations其实不单单是简单的注释,它是与一个程序元素相关联信息或者元数据的标注,它不影响程序的运行,但相关的软件工具或框架能够将其转换成特殊的元数据标记,以方便开发者以更少的代码去提高效率(比如通过。如果你熟悉Java,则会发现在Java SE 5中及象Spring等框架中,都大量使用了Annotations。

  然而,由于php并不象Java那样是编译性语言,因此本身缺乏去解析Annotations的机制,但幸好phpunit去提供了这样的功能,我们以下面的代码为例:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网<?php
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
class MyMathClass
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Add two given values together and return sum
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public function addValues($a,$b)
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
return $a+$b;
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
?>

   上面的只是一个简单的加法的例子,为此,我们使用Annotations去编写一个单元测试,在上两篇文章中,我们采用的是手工编写单元测试的方法,而本文中,将介绍使用phpunit命令行的方法,自动生成单元测试的框架,方法如下:

  首先把上面的类保存为MyMathClass.php,然后在命令行下运行如下命令:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网phpunit Cskeleton-test MyMathClass

   这时phpunit会自动生成如下的框架单元测试代码:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网<?php
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
require_once '/path/to/MyMathClass.php';
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Test class for MyMathClass.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Generated by PHPUnit on 2011-02-07 at 12:22:07.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
class MyMathClassTest extends PHPUnit_Framework_TestCase
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* @var MyMathClass
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
protected $object;
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Sets up the fixture, for example, opens a network connection.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* This method is called before a test is executed.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
protected function setUp()
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$this->object = new MyMathClass;
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Tears down the fixture, for example, closes a network connection.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* This method is called after a test is executed.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
protected function tearDown()
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* @todo Implement testAddValues().
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public function testAddValues()
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
// Remove the following lines when you implement this test.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$this->markTestIncomplete(
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
'This test has not been implemented yet.'
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网);
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
?>
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网

   可以看到,phpunit为我们生成的单元测试代码自动引入了原来的MyMathClass.php,同时也生成了setUp和tearDown方法,但唯一的核心单元测试代码是留给了我们编写。如果想在这个基础上更快速的生成我们想要的单元测试代码,要如何实现呢?没错,就是使用annotations!我们可以在原来的MyMathClass.php中加入如下的annotations。

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网<?php
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
class MyMathClass
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Add two given values together and return sum
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* @assert (1,2) == 3
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public function addValues($a,$b)
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
return $a+$b;
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
?>
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网

  然后再象上述一样在命令行运行:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网  phpunit Cskeleton-test MyMathClass

  这个时候会为我们生成如下的单元测试代码:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网<?php
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Generated from @assert (1,2) == 3.
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public function testAddValues()
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$this->assertEquals(
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
3,
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$this->object->addValues(1,2)
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网);
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
?>
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网

  看到了么?我们在原有的类中加入了注解@assert(1,2)==3,则phpunit自动为我们生成了正确的单元测试代码。当然,可以参考phpunit手册,学习到更多的关于@assert注解使用的规则。

  下面再举一个例子来讲解annotations。假设我们的程序中的一个方法,只是仅需要数据的输入,并且不依赖XML或者数据库提供数据源,则为了测试这个方法,我们可能想到的一个方法是在程序中设置一个测试数据集去测试,但这里介绍一个比较简单的方法,就是使用注解@dataProvider,修改MyMathClass.php如下:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网<?php
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Data provider for test methods below
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public static function provider()
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
return array(
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
array(1,2,3),
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
array(4,2,6),
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
array(1,5,7)
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网);
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* Testing addValues returns sum of two values
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网* @dataProvider provider
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public function testAddValues($a,$b,$sum)
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网{
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$this->assertEquals(
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$sum,
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
$this->object->addValues($a,$b)
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网);
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
?>
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网

   可以看到,这里使用了注解@dataProvider,指明了测试用例的数据提供者是由provider方法返回的一个数组。所以在单元测试时,数组中的第0个元素则会赋值给$a,第1个元素则会赋值给b,第3个元素则会赋值给sum,可以看到,上面的第3个数组提供的数据是不能通过单元测试的,因为1+5不等于7。

  此外,这里还简单介绍两个常用的annotations,比如@expectedException注解可以测试代码中是否正确抛出了异常,比如:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网<?phprequire_once 'PHPUnit/Framework.php';
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
class ExceptionTest extends PHPUnit_Framework_TestCase{    
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
/**  
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网   * @expectedException InvalidArgumentException    
*/    
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
public function testException()    {  
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网  }
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网
?>
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网

   这里就用注解的方法表示testException中必须抛出的异常类型为InvalidArgumentException。

  另外一个是@cover注解。它的作用是标识phpunit只为类中的哪些方法或作用域生成测试代码,比如:

PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网/**
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网     * @covers SampleClass::publicMethod
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网     * @covers SampleClass::<!public>
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网     * @covers HelperClass<extended>
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网    
*/
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网    
public function testMethod()
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网    {
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网        
$result = SampleClass::method();
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网}
PHP单元测试利器 PHPUNIT深入用法(三)第1/2页_信息快讯网

   则phpunit只为SampleClass类中的publicMethod方法、SampleClass类中的所有非public声明的方法和HelperClass类或者它的其中一个父类产生单元测试代码。

php.ini-dist 和 php.ini-recommended 的区别介绍(方便开发与安全的朋友)
php下载文件的代码示例
PHP sprintf() 函数的应用(定义和用法)
php 对输入信息的进行安全过滤的函数代码
PHP删除数组中的特定元素的代码
PHP Warning: PHP Startup: Unable to load dynamic library \ D:/php5/ext/php_mysqli.dll\
PHP Parse Error: syntax error, unexpected $end 错误的解决办法
php提示undefined index的几种解决方法
PHP运行出现Notice : Use of undefined constant 的完美解决方案分享
一些需要禁用的PHP危险函数(disable_functions)
PHP中创建空文件的代码[file_put_contents vs touch]
php数组函数序列之array_push() 数组尾部添加一个或多个元素(入栈),返回新长度。
PHP-CGI进程CPU 100% 与 file_get_contents 函数的关系分析
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
PHP导出MySQL数据到Excel文件(fputcsv)
PHPUnit PHP测试框架安装方法
PHP数组交集的优化代码分析
PHP单元测试利器 PHPUNIT深入用法(二)第1/2页
PHP单元测试利器 PHPUNIT初探第1/2页
php下安装配置fckeditor编辑器的方法
PHP如何抛出异常处理错误
php中实现记住密码自动登录的代码
PHP中删除变量时unset()和null的区别分析
php的日期处理函数及uchome的function_coomon中日期处理函数的研究
php !function_exists("T7FC56270E7A70FA81A5935B72EACBE29"))代码解密
php iconv() : Detected an illegal character in input string
php 随机记录mysql rand()造成CPU 100%的解决办法
PHP 模拟$_PUT实现代码
©2014-2024 dbsqp.com