你是否在程序开发的过程中遇到下面的情况:当你花了非常长的时间开发一个应用后,你觉得应该是大功告成了,可惜在调试的时候,老是不断的发现bug,并且最可怕的是,这些bug是反复出现的,你可能发现这些bug之间会有关联,但却老是找不到问题的所在。

  当你遇到以上这些令你沮丧的情况时,你一定会想能有什么更好的办法去解决呢?办法当然是有的!这就是使用单元測试。单元測试不但能够在一定程度上解决上述头疼的问题,并且能让代码变的easy维护,还能够能让你很多其它地对代码进行重构。

  一旦你编写好单元測试用例,当你须要改动你的代码时,你要做的事情就是又一次执行你的单元測试用例并观察这些单元測试用例是否能通过,假设通过了的话,证明代码是没问题的。

  人们往往会说:既然单元測试这么好,为什么那么多人还是不大愿意去写单元測试呢?有下面几种理解上的误曲:

  1、觉得编写单元測试太浪费时间。尽管眼下非常多IDE工具都为编写单元測试建立好了框架,但还是要开发人员编写一些单元測试的代码的。就象非常多开发中的最佳实践一样,用正确的方法去做正确的事情会为开发节省大量的时间。每当新添加新功能时,你可能通过訪问你的网页到处去点击手动測试,而执行建立好的单元測试用例其速度事实上比通过手工去測试的速度更快。

  2、觉得既然代码能执行了,不须要再编写单元測试。但假设团队中有新的成员,假设没有良好的单元測试用例,新成员非常有可能任意地去编码而不考虑各种后果。假设有编写良好的单元測试,在程序执行时进行各种測试,则能最大程度避免bug的产生。

  3、觉得编写单元測试代码枯燥无味。程序猿的天性是解决这个问题,而非常多程序猿觉得在紧张的编码工作时,还要编写单元測试代码,会非常枯燥。但要知道的是,假设能通过编写单元測试在非常早的阶段就能尽可能发现代码中多的错误的话,那么既节省时间降低了出错,何乐而不为?

  開始动手安装phpunit

  本文中将通过介绍php中的单元測试利器phpunit(http://phpunit.de/),并通过实际样例来解说怎样在实际工作中运用phpunit。首先安装phpunit的方法能够通过php下的pear去安装:

  1.   pear channel-discover pear.phpunit.de
  2.   pear channel-discover components.ez.no
  3.   pear channel-discover pear.symfony-project.com
  4. pear install phpunit/PHPUnit

假设你想通过手动方式去安装,能够參考phpunit的手冊去安装(http://www.phpunit.de/manual/3.0/en/installation.html)。

  编写第一个单元測试用例

  以下我们開始编写第一个单元測试用例。在编写測试用例时,要遵守例如以下的phpunit的规则:

  1 一般地,在測试用例中,能够扩展PHPUnit_Framework_TestCase类,这样就能够使用象setUp(),tearDown()等方法了。

  2 測试用例的名字最好是使用约定俗成的格式,即在被測试类的后面加上”Test”,比方要測试的类为RemoteConnect,则測试用例的命名为RemoteConnectTest。

  3 在一个測试用例中的全部的測试方法,在命名时都应该以test+測试方法名去命名,如testDoesLikeWaffles(),要注意的是该方法必须是声明为public类型的。当然能够在你的測试用例中包括private的方法,但它们不能被phpunit所调用。

  4 測试方法中是不能接收參数的。

  以下首先举个简单的样例,代码例如以下:

  1. <?php
  2. class RemoteConnect
  3. {
  4. public function connectToServer($serverName=null)
  5. {
  6. if($serverName==null){
  7. throw new Exception(“That's not a server name!”);
  8. }
  9. $fp = fsockopen($serverName,80);
  10. return ($fp) ? true : false;
  11. }
  12. public function returnSampleObject()
  13. {
  14. return $this;
  15. }
  16. }
  17. ?>

上面的代码事实上是实现连接到一个指定的服务器的功能,那么我们能够编写測试代码例如以下:

  1. <?php
  2. require_once('RemoteConnect.php');
  3. class RemoteConnectTest extends PHPUnit_Framework_TestCase
  4. {
  5. public function setUp(){ }
  6. public function tearDown(){ }
  7. public function testConnectionIsValid()
  8. {
  9. // test to ensure that the object from an fsockopen is valid
  10. $connObj = new RemoteConnect();
  11. $serverName = 'www.google.com';
  12. $this->assertTrue($connObj->connectToServer($serverName) !== false);
  13. }
  14. }
  15. ?>

 在上面的代码中,因为继承了PHPUnit_Framework_TestCase类,因此在setUp和tearDown方法中,不须要编写不论什么代码。SetUp方法是在每一个測试用例执行前进行一些初始化的工作,而tearDown则在每一个測试用例执行后进行一些比方资源的释放等工作。在測试方法中,通过使用phpunit的断言assertTrue去推断所返回的布尔值是否为真,这里是通过调用RemoteConnect.php中的connectToServe方法去推断是否能连接上server。

接下来我们执行这个单元測试,在命令行下输入代码:

  phpunit /path/to/tests/RemoteConnectTest.php就可以,能够看到測试顺利通过的话,会输出下面结果:

  1. PHPUnit 3.4 by Sebastian Bergmann.
  2. Time: 1 second
  3. Tests: 1, Assertions: 1, Failures 0

能够看到,上面是通过了測试。默认情况下,phpunit是会执行測试用例中的全部測试方法的。以下再介绍下phpunit中相关的几个断言:

  1. AssertTrue/AssertFalse 断言是否为真值还是假
  2. AssertEquals 推断输出是否和预期的相等
  3. AssertGreaterThan 断言结果是否大于某个值,相同的也有LessThan(小于),GreaterThanOrEqual(大于等于),
  4. LessThanOrEqual(小于等于).
  5. AssertContains 推断输入是否包括指定的值
  6. AssertType 推断是否属于指定类型
  7. AssertNull 推断是否为空值
  8. AssertFileExists 推断文件是否存在
  9. AssertRegExp 依据正則表達式推断

举个样例来说明下比方AssertType的使用,依旧以上面的样例来说,能够用AssertType去推断returnSampleObject返回的对象实例是否为remoteConnect,代码例如以下:

  1. <?php
  2. function testIsRightObject() {
  3. $connObj = new RemoteConnect();
  4. $returnedObject = $connObj->returnSampleObject();
  5. $this->assertType('remoteConnect', $returnedObject);
  6. }
  7. ?>

 眼下PHP框架对单元測试的支持

  眼下非常多优秀的php框架(如Zend Framework,Symfony等),都提供了对单元測试非常好的支持。以Zend Framework为例,说明下当中是怎样执行单元測试的。

  1. <?php
  2. class CommentControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
  3. {
  4. public function setUp()
  5. {
  6. parent::setUp();
  7. }
  8. public function tearDown()
  9. {
  10. parent::tearDown();
  11. }
  12. public function appBootstrap()

PHP单元測试利器:PHPUNIT深入使用方法(二)

http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2011/0216/7535.html

php单元測试的更多相关文章

  1. 利用Continuous Testing实现Eclipse环境自己主动单元測试

    当你Eclipse环境中改动项目中的某个方法时,你可能因为各种原因没有执行单元測试,结果代码提交,悲剧就可能随之而来. 所幸infinitest(http://infinitest.github.io ...

  2. 在Eclipse中使用JUnit4进行单元測试(0基础篇)

    本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,须要写成千上万个方法或函数,这些函数的功能可能 ...

  3. C语言单元測试

    C语言单元測试 对于敏捷开发来说,单元測试不可缺少,对于Java开发来说,JUnit非常好,对于C++开发,也有CPPUnit可供使用,而对于传统的C语言开发,就没有非常好的工具可供使用,能够找到的有 ...

  4. OpenStack中给wsgi程序写单元測试的方法

    在 OpenStack 中, 针对web应用, 有三种方法来写单元測试 1) 使用webob生成模拟的request from __future__ import print_function imp ...

  5. Android单元測试之JUnit

    随着近期几年測试方面的工作慢慢火热起来.常常看见有招聘測试project师的招聘信息.在Java中有单元測试这么一个JUnit 方式,Android眼下主要编写的语言是Java,所以在Android开 ...

  6. 让你提前认识软件开发(19):C语言中的协议及单元測试演示样例

    第1部分 又一次认识C语言 C语言中的协议及单元測试演示样例 [文章摘要] 在实际的软件开发项目中.常常要实现多个模块之间的通信.这就须要大家约定好相互之间的通信协议,各自依照协议来收发和解析消息. ...

  7. Android 进行单元測试难在哪-part3

    原文链接 : HOW TO MAKE OUR ANDROID APPS UNIT TESTABLE (PT. 1) 原文作者 : Matthew Dupree 译文出自 : 开发技术前线 www.de ...

  8. iOS 单元測试之XCTest具体解释(一)

    原创blog,转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS-SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...

  9. Android下的单元測试

    android下的单元測试 在AndroidManifest.xml文件里配置下面信息: 在manifest节点下加入: <!-- 指定測试信息和要測试的包 --> <instrum ...

随机推荐

  1. JavaSE复习日记 : 递归函数

    /* * 递归函数 * 什么是递归? * 在一个方法的内部,对自身进行调用,又叫做递归调用 * * 递归和循环的编写都包括三部分: * 1. 初始值; * 2. 终止条件; * 3. 前进步长; * ...

  2. 小测试 php代理,nginx代理,直接访问对比

    #php proxy total sent request num: 507 total handle read times: 506 506 fetches, 2 max parallel, 2.7 ...

  3. linux grep 指定字符串的正则表达式

    cat all_uuid_log | grep "[a-z0-9]\{32\}"

  4. Hibernate学习之检索策略

    一.类级别的检索策略 类级别可选的检索策略包括立即检索和延迟检索, 默认为延迟检索 –立即检索: 立即加载检索方法指定的对象 –延迟检索: 延迟加载检索方法指定的对象,在使用具体的属性时,再进行加载 ...

  5. C++学习之引用

    C++学习之引用         临时变量.引用参数和const         现在,当参数为const引用的时候,如果实参与引用参数不匹配,C++将生成临时变量.C++将在下面两种情况下生成临时变 ...

  6. JavaScript版排序算法

    JavaScript版排序算法:冒泡排序.快速排序.插入排序.希尔排序(小数据时,希尔排序会比快排快哦) //排序算法 window.onload = function(){ var array = ...

  7. 从零开始PHP学习 - 第二天

    写这个系列文章主要是为了督促自己  每天定时 定量消化一些知识! 同时也为了让需要的人 学到点啥~! 本人技术实在不高!本文中可能会有错误!希望大家发现后能提醒一下我和大家! 偷偷说下 本教程最后的目 ...

  8. Windows Phone 8.1 发送http 网络请求。

    在windows phone 8.1 中可以用 HttpClient 类来发送http 请求. 例子: try { Uri uri = new Uri(@"http://api.map.ba ...

  9. Java—异常处理总结

    异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出 ...

  10. 怎样从一个DLL中导出一个C++类

    原文作者:Alex Blekhman    翻译:朱金灿 原文来源: http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx 译 ...