PHPUnit 袖珍指南(中文)(转贴)

上一篇 / 下一篇  2010-11-12 00:33:14

PHPUnit袖珍指南
速查,参考
Sebastian Bergmann

本作品遵循Creative Commons Attribution License授权许可。可访问http://creativecommons.org/licenses/by/2.0/或发信至Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA来查看本授权(license)。

适用于PHPUnit 3.2版,2008-03-15更新。

前言

    必备条件
    自由,免费
    本书约定
    鸣谢

1. 自动化测试
2. PHPUnit的目标
3. 安装PHPUnit
4. 编写PHPUnit测试

    数据提供者
    测试异常

5. 命令行测试启动器
6. Fixtures

    setUp()多tearDown()少
    变异
    共享Fixture

7. 组织测试套件

    套件级装配器

8. 测试用例扩展

    测试输出
    测试性能

9. 数据库测试

    数据集(暂无内容)

        平整的XML数据集(暂无内容)
        XML数据集(暂无内容)

    操作(暂无内容)
    数据库测试最佳实践(暂无内容)

10. 未完成和跳过的测试

    未完成的测试
    跳过的测试

11. 模拟对象

    自分流
    存根

12. 测试实践

    开发期间
    调试期间

13. 测试优先程序设计

    银行账户实例

14. 代码覆盖率分析

    指定覆盖的方法
    忽略代码块
    包含和排除文件

15. 测试的其他用途

    敏捷文档
    跨团队测试

16. 日志

    XML格式
    代码覆盖率(XML)
    JavaScript对象表示法(JSON)
    Test Anything Protocol(TAP)
    GraphViz标记
    测试数据库

17. 软件度量(暂无内容)

    项目混乱检测器(暂无内容)

18. 框架(Skeleton)生成器

    注解

19. PHPUnit和Selenium

    Selenium RC
    PHPUnit_Extensions_SeleniumTestCase

20. 持续集成

    CruiseControl
    Apache Maven

21. PHPUnit的执行
22. PHPUnit API

    概述
    PHPUnit_Framework_Assert
    PHPUnit_Framework_Test
    PHPUnit_Framework_TestCase
    PHPUnit_Framework_TestSuite
    PHPUnit_Framework_TestResult
    包结构

23. 扩展PHPUnit

    子类化PHPUnit_Framework_TestCase
    断言类
    子类化PHPUnit_Extensions_TestDecorator
    实现PHPUnit_Framework_Test
    子类化PHPUnit_Framework_TestResult
    实现PHPUnit_Framework_TestListener
    新测试运行器

A. XML配置文件

    测试套件
    分组
    包含及排除用于代码覆盖率的文件
    日志

        PMD规则

    设置PHP INI和全局变量

B. 用于PHP 4的PHPUnit
C. 索引

D. 参考书目
E. 版权

前言

“你打算何时写PHPUnit文档?”对于这个问题,长久以来,我的回答是“你不需要PHPUnit文档。只需阅读JUnit的文档或者买本关于JUnit的书籍,将用于JUnit的Java代码示例改编为用于PHPUnit的PHP代码即可。” 当我向O'Reilly德国办事处的Barbara Weiss和Alexandra Follenius谈及这些,他们鼓励我考虑是不是写本可作为PHPUnit文档的书。
必备条件

本书讨论的是PHPUnit,一个用于采用PHP程序设计语言进行测试驱动开发的开源框架。本版次适用于3.2版的PHPUnit。当然,大多数示例应该也可用于2.0-3.1版的PHPUnit。本书后面的“用于PHP 4的PHPUnit”(附录B - 译注)部分涉及了适用于PHP 4的旧版PHPUnit,它们已不再积极开发。

读者需要很好的理解使用PHP 5进行面向对象程序设计。对于德国读者,我可以推荐我写的书,[Bergmann2005],作为PHP 5 OOP的入门。一本关于此主题的英文书是Andi Gutmans、Stig Bakken和Derick Rethans的[GuBaRe2005]。
自由,免费

本书须在遵循Creative Commons Attribution License的情况下使用。你可在本书站点的http://www.phpunit.de/pocket_guide/找到它的最新版本。你可以对本书作任意修改并分发。当然,相对于发布你自己的私有版本,我更希望你将反馈和补丁发送至<sb@sebastian-bergmann.de>。
本书约定

下面是本书排版方面的一些约定:

斜体字

    指示新的术语、URL、电邮地址、文件名、文件扩展名、路径名、目录和Unix实用程序。
等宽字体

    指示命令、选项、开关、变量、函数、命名空间、方法、模块、参数、值、对象、文件内容或者命令输出。
等宽粗体

    显示应由用户输入的命令或其他文本。
等宽斜体

    显示应被用户提供的值替换的文本。

你应该特别留意采用下列样式从(一般)文本中分离出来的注意点:
注意

这是个提示、建议或者常规注意。它含有关于在谈话题的有用的辅助信息。
警告

这是个警告或提醒。
鸣谢

我要感谢Kent Beck和Erich Gamma开发了JUnit,给了我编写PHPUnit的灵感。还要感谢Kent Beck写了“JUnit Pocket Guide”[Beck2004],激起了我写本书的念头。感谢本书的发起者,O'Reilly的Allison Randal、Alexandra Follenius和Barbara Weiss。

感谢Andi Gutmans、Zeev Suraski和Marcus Börger在PHP 5的核心,Zend引擎2方面的工作。感谢Derick Rethans开发了Xdebug,这个PHP扩展让PHPUnit拥有了(分析)代码覆盖率功能。最后,感谢模拟对象系统的初始开发者Jan Borsodi、协助制作代码覆盖率报表生成程序的Michael Lively Jr.和Jan Kneschke,还有为Phing编写PHPUnit任务的Michiel Rook。
第 1 章 自动化测试

再好的程序员也会犯错.程序员的好坏区别在于,好的程序员尽可能早地利用测试检测错误所在。越早测试,发现错误的机会越大,发现和修正的代价就越小。这解释了为什么在软件发布前才进行测试会有那么多问题。大多数错误都未被发现,而且修正已发现错误的代价如此之大,以至于你必须有选择地进行处理,因为根本不可能全部修复。

使用PHPUnit进行测试与你曾经的做法并非完全不同。它只是在操作方式上有所不同。区别在于测试和执行成套测试,前者检查程序行为是否符合预期,后者是可运行的代码片断,它们自动测试软件各部分(单元)的正确性。这些可运行的代码片断称为单元测试

本章我们从简单的基于print的测试代码开始,到完整的自动化测试(结束)。假设要我们测试PHP内建的array。一个要测试的功能是函数sizeof()。对于新建的数组,我们期望sizeof()函数返回0。假如一个元素后,sizeof()应该返回1。范例 1.1是我们要测试的(代码)。

范例 1.1: 测试数组和sizeof()

<?php
$fixture = array();
// $fixture应该为空。
 
$fixture[] = 'element';
// $fixture应该含有一个元素。
?>


检查我们是否得到预期结果的简单方法是在增加元素前后显示sizeof()的结果(见Example 1.2)。如果先后得到0和1,array和sizeof() 行为符合预期。

范例 1.2: 使用print测试数组和sizeof()

<?php
$fixture = array();
print sizeof($fixture) . "\n";
 
$fixture[] = 'element';
print sizeof($fixture) . "\n";
?>

0
1


现在,我们要把需要人工解释(结果)的测试变为自动运行的测试。在范例 1.3中,我们把预期值和实际值的比较写入测试代码,如果相同就输出ok。一旦看到not ok消息,我们就知道有错误。

范例 1.3: 比较预期值和实际值以测试数组和sizeof()

<?php
$fixture = array();
print sizeof($fixture) == 0 ? "ok\n" : "not ok\n";
 
$fixture[] = 'element';
print sizeof($fixture) == 1 ? "ok\n" : "not ok\n";
?>

ok
ok


现在我们把预期值和实际值得比较提取出来,放入一个函数,它会在存在差异时扔出一个异常。(范例 1.4)。这有2个好处:编写测试变得更容易,而且只在出错时产生输出。

范例 1.4: 使用断言函数测试数组和sizeof()

<?php
$fixture = array();
assertTrue(sizeof($fixture) == 0);
 
$fixture[] = 'element';
assertTrue(sizeof($fixture) == 1);
 
function assertTrue($condition)
{
    if (!$condition) {
        throw new Exception('Assertion failed.');
    }
}
?>


现在测试完全自动化了。相对于我们的第一版测试,该版已是自动化测试。

使用自动化测试的目的是少犯错。即使有了极好的测试,你的代码仍不理想,一旦开始自动化测试,你将会发现缺陷明显减少。自动化测试确保你的代码的可信性。这种可信性使你可以在设计上做出更大胆的跨越(解构),同队友合作得更好(跨团队测试),改善同客户的关系,并且每晚安心回家,因为(事实)证明你的努力使系统比以前更好了。
第 2 章 PHPUnit的目标

目前为止,我们只有2个用于内建的array和sizeof()函数的测试。当我们开始测试PHP提供的众多array_*()函数时,我们将需要为它们中的每一个都编写一个测试。我们可以从头开始为所有的测试编写基础设施。然而,一次性地编写一个测试基础设施并且只编写每个测试的特有部分会更好。PHPUnit就是这样的一个基础设施。

类似PHPUnit这样的框架必须解决一系列的限制,其中的一些似乎相互冲突。同时,测试应该:

(编写)易学。

    如果编写测试很难学,开发者就不会去学。
易写。

    如果测试不易编写,开发者就不会去写。
易读。

    测试代码不应引入额外的开销(复杂性? - 译注),以便测试本身不被旁杂干扰。
容易执行。

    测试应该点下按钮就能运行,并且以清晰明确的格式呈现结果。
快速执行。

    测试应该快速运行,以便能够每天运行成百上千次。
相互独立。

    测试不应该相互影响。如果测试的运行顺序改变,测试的结果应该不变。
组合。

    我们应能将任意数量的测试以任意的组合运行。这是相互独立的必然结果。

这些约束中有2个主要的冲突:

(编写)易学 VS 易写。

    通常测试不需要程序语言的全部灵活性。许多测试工具提供它们特有的脚本语言,这些语言只含有编写测试所需特性的最小集。由此测试易于读写,因为没有干扰是你从测试内容分心。然而,学习其他程序语言和程序工具集并不方便,也会干扰思维。
相互独立 VS 快速执行。

    如要一个测试的结果不影响其它测试,每个测试都应在运行前创建完整的运行场景(world)状态,并在结束时将它恢复为原始状态。可是,建立场景需时很久:例如连接数据库并用真实数据初始化为已知状态。

PHPUnit使用PHP作为测试语言来解决这些冲突。有时全功能的PHP对于编写短小直接的测试显得小题大做,但是另一方面PHP让我们可以利用程序员掌握的全部经验和工具。由于我们要说服心怀抵触的测试员,降低编写那些初始测试的门槛是非常重要的。

PHPUnit errs on the side of isolation over quick execution. 独立测试的价值在于它们提供高质量的反馈。你不会看到带有一连串测试失败的报告,这实际上是由测试集开头的一个测试失败弄乱了其他测试的场景引起的。这种趋向于分离的测试鼓励带有大量简单对象的设计。每个对象都能单独被快速测试。由此得到的结果是更好的设计和更快的测试。

PHPUnit 假设多数测试会成功,并且成功测试的细节不值得报告。失败的测试才值得注意和报告。除了统计运行的测试数量,大多数成功的测试无须关注。这个假设被内建于报告类而不是PHPUnit内核中。在测试报告中,你能看到运行了多少测试,但是只有失败的测试才有明细。

测试应该有良好的粒度(划分)-只测试某个对象的某个方面。因此,首次测试失败就会中断测试运行并且PHPUnit会报告该错误。运行众多小测试很巧妙。测试具有良好的粒度会改善系统的总体设计。

使用PHPUnit测试一个对象,你只能利用对象公用接口。让测试仅仅基于公共可见性行为,使你在差劲的设计在系统中广为蔓延之前就能面对和解决困难的设计问题。
第 3 章 安装PHPUnit

PHPUnit应该使用PEAR安装程序安装。它为PHP软件包提供分发系统,是PEAR的支柱,并且从4.3.0版开始随PHP一同发行。

用于分发PHPUnit的PEAR通道(pear.phpunit.de)需要在本地PEAR环境登记:

pear channel-discover pear.phpunit.de

这种做法只需进行一次。现在PEAR安装程序可从PHPUnit通道安装软件包了:

pear install phpunit/PHPUnit

之后,你能在你的本地PEAR目录中见到PHPUnit源代码文件;该路经通常是 /usr/lib/php/PHPUnit.

尽管安装PHPUnit只支持通过PEAR安装,你也能手动安装PHPUnit。对于手动安装,做法如下:

   1.

      从http://pear.phpunit.de/get/下载一个发行存档并解压至你的php.ini配置文件的include_path中列举的一个目录。
   2.

      准备phpunit脚本:
         1.

            将pear-phpunit脚本改名为phpunit。
         2.

            用你得PHP命令行解释器的路径(通常是/usr/bin/php)替换文件中的@php_bin@。
         3.

            将它拷贝到你的PATH中的一个目录并使之可运行(chmod +x phpunit)。
   3.

      准备PHPUnit/Util/Fileloader.php脚本:
         1.

            用你得PHP命令行解释器的路径(通常是/usr/bin/php)替换文件中的@php_bin@。

第 4 章 编写PHPUnit测试

范例 4.1 显示我们必须如何修改范例 1.4中的2各测试以使它们可用于PHPUnit。

范例 4.1: 使用PHPUnit测试数组和sizeof()

<?php
require_once 'PHPUnit/Framework.php';
 
class ArrayTest extends PHPUnit_Framework_TestCase
{
    public function testNewArrayIsEmpty()
    {
        // 创建数组fixture。
        $fixture = array();
 
        // 断言数组fixture的尺寸是0。
        $this->assertEquals(0, sizeof($fixture));
    }
 
    public function testArrayContainsAnElement(

<


TAG: phpunit

 

评分:0

我来说两句

我的栏目

日历

« 2024-04-24  
 123456
78910111213
14151617181920
21222324252627
282930    

我的存档

数据统计

  • 访问量: 3568
  • 日志数: 8
  • 建立时间: 2010-11-11
  • 更新时间: 2010-11-15

RSS订阅

Open Toolbar