PHPUnit中文手册_第1页
PHPUnit中文手册_第2页
PHPUnit中文手册_第3页
PHPUnit中文手册_第4页
PHPUnit中文手册_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、PHPUnit 手册第一章 自动化测试任何优秀的程序员都会犯错。优质的程序与差劲的程序的区别在于优质的程序使用了测试,能够在最快的时间内发现他的错误。你越早做针对错误的测试,越大的机会去发现错误,越少的花费投入到发现和修改错误。这就解释了为什么直到释放软件才进行测试是非常有问题的。很多错误一点都没有被发现,而你修改一个被发现的错误的花费是非常高的,以至于你不得不分类这些错误,你不可能一次性修改所有错误。使用PHPUnit进行测试和你应该做的事(测试)比起来不是完全不同。它仅仅是用不同的方法去做。不同的地方在于,通过执行一连串的测试,就是一些可运行的代码段,会去自动测试软件局部功能的正确性,它能

2、检查你的程序是否如你预期那样执行。这些可运行的代码段被称作单元测试。在这章节,我们将从简单的输出基础测试代码到一个完成的自动测试。想象下,我们被要求去测试PHP内置的数组。一个功能就是测试count()这个函数。对于一个新建的数组,我们期望count()函数返回的是0。当我们添加一个元素时,count()应该返回1.例子1.1向我们展示了我们想要的测试测试1.1:测试数组操作<?php$fixture=array();/$fixture is expected to be empty.$fixture=element;/ $fixture is expected to contain o

3、ne element?>一个简单的检查是否得到我们期望的结果的方法是输出count()的结果在添加一个元素(看例子1.2)的之前和之后。如果我们得到0和1,那么数组和count()的执行是我们期望的那样。例子1.2:用输出来测试数组操作<?php$fixture = array();print count($fixture) . "n" $fixture = 'element'print count($fixture) . "n"?>01现在,我们要摆脱测试需要人工判断,测试需要自动运行。在例子1.3,我们将期望值和实际

4、值的比较写进测试代码,如果两个值相等,则输出ok,如果我们看见一个not ok,我们就知道有些地方错了。例子1.3:比较期望值和实际值来测试数组操作<?php$fixture = array();print count($fixture) = 0 ? "okn" : "not okn" $fixture = 'element'print count($fixture) = 1 ? "okn" : "not okn"?>okok我们现在将比较期望值和实际值分解到一个函数里,当发现不一致时,

5、会抛出一个异常(例子1.4).这样给我们两个好处:这样写测试会变得简单而且我们只有当发生错误时才会得到提示。例子1.4:用一个断言函数来测试数组操作<?php$fixture = array();assertTrue(count($fixture) = 0); $fixture = 'element'assertTrue(count($fixture) = 1); function assertTrue($condition) if (!$condition) throw new Exception('Assertion failed.'); ?>现

6、在,这个测试已经可以被自动完成。不是像我们第一个版本那样测试,而是像最后版本那样,我们有一个自动的测试。这样的自动测试目的是为了犯更少的错误。但你的代码仍然不够完美,即使你用最优秀的测试。你会激动的看到错误的减少,当开始自动测试。自动测试让你对你代码有最可靠的信任。依赖这种信任,你在设计(重构)时,可以进行更大胆的跃进,可以更好得和你的队友协作(跨团队测试),改善你和你客户之间的关系,在每次回家的晚上,你可以获得强有力的证明,在你的努力下,这个系统比今天早上要好很多。第二章. PHPUnit的目标到现在,我们只有两个测试针对内置数组和count()函数。当我们开始测试很多PHP提供的array

7、_*()函数时,我们需要针对每一个写测试。我要写这些测试的框架从零开始。然而,这样做一定更好,如果先写一个测试框架,然后只用写对于每一测试的不同的部分。PHPUnit就是这样的框架像PHPUnit这样的框架要去解决一套约束,一些经常产生在不同人之间的冲突。同时,测试应该是:容易被学会怎么写 如果它很难被学会如何写测试,那么开发者不会去学如何写它。容易写 如果测试不容易写,开发者不会去写它。容易读 测试不应该包含多余的开销,以至于测试自己不会丢失在周围的噪乱的环境中。容易执行 这测试应该有一个可触及的开关按钮并且结果的表示必须在一种清晰不含糊的格式下。快速执行 测试能够快速运行,一天能运行成千上

8、百次。独立 测试不应该相互影响。如果测试运行的顺序有所不同,测试的结果不应该改变。可组合的 我们可以同时运行任意数量或任意组合的测试。这是独立的必然结果。在这些约束存在两个主要的冲突:容易学会写和容易写 测试不会要求对一个语言要有很强的灵活性。很多测试工具证明了他们自己的脚步语言包含很少的需求特点在写测试时。这样的结果的测试容易读和写,因为它没有多余的噪音让你对于测试的内容分心。学习另一种语言和一套程序工具是不方便的且容易扰乱注意力。独立和快速执行 如果你想一个测试的结果不会影响另一个测试的结果,每一个测试都会在他开始执行前创造一个完整的状态,在他完成的时候,返回原始状态。假设这世界可以有很长

9、的时间:举个例子,连接一个数据库并初始化到一个已知的状态使用了一个真实的数据。PHPUnit尝试解决这些冲突,通过把PHP作为测试语言。有时候,这充满能量的PHP过度的伤杀了对于写线性测试,但是用PHP我们可以利用一切现成的经验和工具程序。后来我们努力尝试说服不情愿的测试者,降低书写初级测试的门槛是非常重要的。PHPUnit 勘误既能保证快速执行又能保证独立性。独立的测试是有价值的,因为他们提供了高质量的反馈。你不会拿到有一堆测试错误的报告,而仅仅因为一个测试在开始时造成错误导致剩下其他测试的混乱。这个方向是朝鼓励设计出有众多简单的部件的独立测试。这样做的结果会是更好的设计,更快的测试。PHP

10、Unit认为假设大多数测试成功,那就没有必要关于成功测试的详尽报告。而当测试失败时,这是值得去解释和报告的。绝大多数测试应该成功的且不值得讨论除了有多少个测试被运行。这个假设是在报告类里面而不是在PHPUnit核心里。当测试结果出来时,你会看到多少测试被执行,但是你只会看到错误测试的详尽信息。测试要精细,测试项目的一个方面。因此,当测试第一次失败,测试的执行会停止,PHPUnit会报告这次失败。做测试包含许多小测试是一种艺术。精细的测试能提供系统的整体设计。当你用PHPUnit测试一个项目时,你要做的就是通过项目公共接口。测试只基于公开的明显的行为。鼓励你早点面对和解决困难的设计问题,在差劲的

11、设计影响大部分系统之前。第三章 安装PHPUnitPHPUnit应该使用pear安装程序安装。这个安装程序是pear的主干,提供给针对php包的分配系统,包括从php4.3.0以来的所有版本。注意PHPUnit 3.6要求php5.2.7(或后来的)但PHP 5.3.3(或后来的)更被推荐。PHP_CodeCoverage,这个库被PHPUnit用来收集和处理代码覆盖信息,需要Xdebug 2.0,。5(或后来的)推荐使用Xdebug 2.1.0(或后来的)用来分配PHPUnit的PEAR频道需要用本地的PEAR环境。此外PHPUnit的组成依赖与PEAR频道。pear channel-dis

12、cover pear.phpunit.depear channel-discover components.ez.nopear channel-discover pear.symfony-这些只用做一次。现在PEAR程序可以用来安装来自PHPUnit频道的程序包了pear install phpunit/PHPUnit在安装后,你可以发现PHPUnit的源文件在你本地的PEAR目录里;这个路径一般是/usr/lib/php/PHPUnit第4章 用PHPUnit写测试例子 4.1向我们展现了如何用PHPUnit写测试,对于PHP的数组操作。这个例子解释了用PHPUnit写测试的基本约定和步骤:

13、1. 这个测试对于一个类Class在另一个类ClassTest里面2. ClassTest 继承PHPUnit_Framework_TestCase3. 这个测试有个公共的方法被命名为test*。或者,你可以用test注释在一个方法的文档块,去注释表面这是一个测试方法4. 在测试方法里,断言方法像assertEquals()(看断言章节)用来判断实际值和预期值是否匹配。例子 4.1:用PHPUnit测试数组操作<?phpclass StackTest extends PHPUnit_Framework_TestCase public function testPushAndPop() $

14、stack = array(); $this->assertEquals(0, count($stack); array_push($stack, 'foo'); $this->assertEquals('foo', $stackcount($stack)-1); $this->assertEquals(1, count($stack); $this->assertEquals('foo', array_pop($stack); $this->assertEquals(0, count($stack); ?>如

15、何时候当你想输出一些东西到屏幕来调试时,一定要把它写的像一个测试-Martin Fowler测试依赖性写单元测试首先要作为一个好习惯,来帮助开发者识别和修改bug,去重构代码,去服务,就像文档对于一个软件单元在测试下。去获取这些好处,单元测试理论上应该覆盖在程序里所有可能的路径。一个单元测试一般覆盖一个特殊路径在一个函数或方法里。但是测试方法不需要一个封闭、独立的实体。经常有暗含的依赖存在于方法之间,藏在实现一个测试中。-Adrian Kuhn et.alPHPUnit 支持声明测试方法间的依赖性。这样的依赖性没有定义测试执行的顺序而他们跟随一个生产者的测试实例返回和传递给依赖的用户l 一个生

16、产者是一个产生测试下单元的测试方法,就像返回数值l 一个用户是一个依赖一个或多个工厂和它们的返回值的测试方法例子4.2展示了如何用depends注释来表达测试方法间的依赖例子4.2:用depends注释表达依赖性<?phpclass StackTest extends PHPUnit_Framework_TestCase public function testEmpty() $stack = array(); $this->assertEmpty($stack); return $stack; /* * depends testEmpty */ public function t

17、estPush(array $stack) array_push($stack, 'foo'); $this->assertEquals('foo', $stackcount($stack)-1); $this->assertNotEmpty($stack); return $stack; /* * depends testPush */ public function testPop(array $stack) $this->assertEquals('foo', array_pop($stack); $this->as

18、sertEmpty($stack); ?>在例子中,一个测试,testEmpty(),创建了一个新数组和是否是空的断言。这个测试如何返回数组作为结果,第二个测试,testPush(),依赖于testEmpty()和传递这结果作为论证,最后,testPop依赖testPush()。为了快速定位错误,我们要把我们的注意集中在重要失败测试。这就是为什么PHPUnit跳过了一个测试当它所依赖的测试失败时。这样提高了错误的定位通过利用测试间的依赖性,如例子4.3例子4.3:利用测试间的依赖性<?phpclass DependencyFailureTest extends PHPUnit_Fr

19、amework_TestCase public function testOne() $this->assertTrue(FALSE); /* * depends testOne */ public function testTwo() ?>phpunit -verbose DependencyFailureTestPHPUnit 3.6.0 by Sebastian Bergmann.FSTime: 0 seconds, Memory: 5.00MbThere was 1 failure:1) DependencyFailureTest:testOneFailed asserti

20、ng that false is true./home/sb/DependencyFailureTest.php:6There was 1 skipped test:1) DependencyFailureTest:testTwoThis test depends on "DependencyFailureTest:testOne" to pass.FAILURES!Tests: 1, Assertions: 1, Failures: 1, Skipped: 1.一个测试可能会有超过一个的depends注释。PHPUnit不会改变测试被执行的顺序,你需要确保具有依赖性的测试

21、能被执行在测试之前。数据提供一个测试方法能接受任意参数。这些参数可以由数据提供方法来提供(例子4.4中provider())。这个数据提供方法可以用指定的dataProvider来注释。一个数据提供方法必须是public并且也返回一些数组或一个对象实现迭代的接口,生成每次迭代的数组。对于每一个数组,它是集合的一部分,测试方法将被调用,作为它的参数数组的内容。例子4.4:用数据提供器返回一系列数组。<?phpclass DataTest extends PHPUnit_Framework_TestCase /* * dataProvider provider */ public funct

22、ion testAdd($a, $b, $c) $this->assertEquals($c, $a + $b); public function provider() return array( array(0, 0, 0), array(0, 1, 1), array(1, 0, 1), array(1, 1, 3) ); ?>phpunit DataTestPHPUnit 3.6.0 by Sebastian Bergmann.FTime: 0 seconds, Memory: 5.75MbThere was 1 failure:1) DataTest:testAdd wit

23、h data set #3 (1, 1, 3)Failed asserting that 2 matches expected 3./home/sb/DataTest.php:9FAILURES!Tests: 4, Assertions: 4, Failures: 1.例子4.5:用数据提供返回迭代对象<?phprequire 'Csv' class DataTest extends PHPUnit_Framework_TestCase /* * dataProvider provider */ public function testAdd($a, $b, $c) $t

24、his->assertEquals($c, $a + $b); public function provider() return new Csv('data.csv'); ?>phpunit DataTestPHPUnit 3.6.0 by Sebastian Bergmann.FTime: 0 seconds, Memory: 5.75MbThere was 1 failure:1) DataTest:testAdd with data set #3 ('1', '1', '3')Failed asserting

25、that 2 matches expected '3'./home/sb/DataTest.php:11FAILURES!Tests: 4, Assertions: 4, Failures: 1.例子4.6:Csv 类<?phpclass Csv implements Iterator protected $file; protected $key = 0; protected $current; public function _construct($file) $this->file = fopen($file, 'r'); public fun

26、ction _destruct() fclose($this->file); public function rewind() rewind($this->file); $this->current = fgetcsv($this->file); $this->key = 0; public function valid() return !feof($this->file); public function key() return $this->key; public function current() return $this->curr

27、ent; public function next() $this->current = fgetcsv($this->file); $this->key+; ?>注意当测试接受输入来自dataProvider方法和来自一个或多个测试它所依赖的,数据提供器提供的参数会优先于来自依赖测试。注意当一个测试依赖一个用了数据提供器的测试时,这个被依赖的测试会被执行,当测试时,最后一个数据成功执行。这个用了数据提供器的测试结果不好被添加进一个被依赖的测试中。测试异常例子4.7表现了如何用expectedException注释去测试一个异常情况是否被包含在被测试代码里。例子4.7:用expectedException注释<?phpclass ExceptionTest extends PHPUnit_Framework_TestCase /* * expectedException InvalidArgumentException */ public function testException() ?>phpunit ExceptionTestPHPUnit 3.6.0

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论