驱动测试开发的几条TIPs

拿到《测试驱动开发》这本书10天左右, 我便"粗鲁"的把它看了一遍, 说是粗鲁, 是因为我这是我一次正式的阅读关于极限编程的书籍, 同时又看的比较快, 对于诸多内容有些囫囵吞枣的嫌疑. 尽管如此, 我还是不得不感叹 Kent Beck(作者)的伟大思想, 给我感觉测试驱动开发更是一门方法学, 而非简单的软件工程解决方案.
激动与感慨之余, 顺便从书中摘抄了一些比较重要的TIps.

1.从测试开始, 而不是从建立对象开始.

2.测试开始之前, 写一个包含所有你认为必须要编写的测试的清单. 最后, 列出所有你认为这一轮编程结束后为了获得整洁代码而必须要完成的重构.

3.开始时的目的是为了让测试能够运行, 而非获得完美的解决方案.

4.测试驱动培养的是你在软件开发中一小步一小步的进行开发的能力, 而非教条的一小步一小步的进行开发.

5.首先解决目标的可用性, 之后再解决代码整洁性的问题.

6.尽量减少测试程序和代码之间的耦合度.

7.如果引入了新的测试, 你需要把新的测试记在清单上.

8.除非有更好的动机,否则不要引入过多的设计.

9.每一个周期,考虑重构一次代码,去掉重复部分.clear一下代码.

10.各种测试之间应该没有任何的相互影响.

11.相互独立的测试意味着所有的测试都是不依赖于顺序的.

12.试着从一开始就编写断言.

13.使用让人容易理解的测试数据.

14.测试从不做任何工作开始.

15.一次只解决一个问题.

16.注意休息.

相关资源:  
1 PHP测试驱动开发介绍
2 豆瓣讨论

PHPUnit简单入门

Php的测试驱动开发闻之已久,却从来没有试用过,今天又看到相关的介绍,就花了点时间简单的看了下. 以下为从官方实例翻译过的来笔记:

从一个案例开始
  通常我们在测试我们的php程序时,会使用诸如print,echo等语句来输出一些结果,以查看我们的程序是否正常或者哪里出错.例如:

<?php   

$array array();   

print sizeof($array);   

array_push($array‘newElement’);   

print sizeof($array);  

结果
0
1
这样我们就知道$array变量是我们预期的结果.现在我们希望能够直观给出测试的结果,而不是看到0, 1这样的结果后再去判断. 我们修改测试代码:

<?php   

$array array();   

print (sizeof($array) == 0) ? "OK\n" "Not Ok\n";   

array_push($array‘newElement’);   

print (sizeof($array) == 1) ? "OK\n" "Not Ok\n"

结果
OK
OK

为了方便重用及修改我们将测试代码的断言部分置于函数中

<?php   

$array array();   

assertTrue(sizeof($array) == 0);   

array_push($array‘newElement’);   

assertTrue(sizeof($array) == 1);   

  

function assertTrue($condition)   

{   

  if (!$condition)   

    throw new Exception(‘Assertion Failed!’);   

}  

 

如此我们就可以简单的实现测试的自动化了.
自动测试的目的是减少错误,使用自动测试你能够明显发现你的代码的错误的减少.还有一些其他的好处……PHPUnit的目标就是如此.那么我们开始我们的PHP Unit Test吧.

一.  安装PHPUnit需要使用Pear Installer安装, 加入phpunit频道到pear寻找频道

D:\wamp\bin\php\php5.2.6>pear channel-discover pear.phpunit.de
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded

安装PHPUnit
D:\wamp\bin\php\php5.2.6>pear install phpunit/PHPUnit
Did not download optional dependencies: pear/Image_GraphViz, pear/Log, use –all
deps to download automatically
phpunit/PHPUnit can optionally use package "pear/Image_GraphViz" (version >= 1.2
.1)
phpunit/PHPUnit can optionally use package "pear/Log"
phpunit/PHPUnit can optionally use PHP extension "pdo_sqlite"
phpunit/PHPUnit can optionally use PHP extension "xdebug" (version >= 2.0.0)
downloading PHPUnit-3.3.4.tgz …
Starting to download PHPUnit-3.3.4.tgz (268,962 bytes)
………………………………………………..done: 268,962 bytes
install ok: channel://pear.phpunit.de/PHPUnit-3.3.4

安装成功,在pear路径下即可看到PHPUnit文件夹,所有PHPUnit源码都在其中.

成功安装之后,会在PHP主目录下生成一个PHPUnit.bat的文件, 这样我们编写测试用例之后可以在命名行下使用如下的语法即可自动进行测试:
> PHPUnit test_begin.php
test_begin.php为包含了测试用例的文件

对每个测试,PHPUnit命令行测试工具打印一个字符表示进程:

  测试成功打印“.”。

  运行测试方法发生了断言失败打印“F”。

  运行测试方法发生了错误打印“E”。

二.  开始一个简单的示例
对于刚刚在开始中的示例(测试数组大小),我们可以使用PHPUnit来编写自动化测试代码了:

<?php   

//filename: test_begin.php   

  

require_once(‘PHPUnit/Framework.php’);   

  

class ArrayTest extends PHPUnit_Framework_TestCase   

{       

  public function testNewArrayIsEmpty()       

  {           

    // 定义一个数组变量           

    $fixture array();            

    // 断言数组的大小为0.           

    $this->assertEquals(0, sizeof($fixture));       

  }        

     

  public function testArrayContainsAnElement()       

  {           

    // 定义一个数组变量           

    $fixture array();            

    // 为数组变量增加一个元素           

    $fixture[] = ‘Element’;            

    // 断言该数组大小为1           

    $this->assertEquals(1, sizeof($fixture));       

  }   

}  

 

> PHPUnit test_begin.php
结果:
PHPUnit 3.3.4 by Sebastian Bergmann.

..

Time: 0 seconds

OK (2 tests, 2 assertions)

..  表示两次测试成功

这个例子显示了使用PHPUnit编写测试用例的基本步骤:
1.  测试类名为ClassTest,其中Class为你的对象名
2.  测试类ClassTest通常派生自PHPUnit_Framework_TestCase
3.  测试通常是一些名称为test*的公共方法. 另一种方法是, 你可以在方法的注释说明中使用@test 标记来表明这是一个测试方法.
4.  诸如assertEquals之类的方法用以测试一个实际值同预想值是否相对.

一个测试方法可以接受任何的参数(任意类型和数量), 参数通过provider()方法来提供,或者同测试方法一下,使用@dataProvider注释标记来标明.关于provider()的返回参数也有一定要求: 要么是数组(每个数据作为一个参数, 数组中可以包含多组参数), 要么是实现了Iterator接口的对象

 

<?php   

class DataTest extends PHPUnit_Framework_TestCase   

{   

    /**  

     * @dataProvider provider  

     */  

    public function testAdd($a$b$c)   

    {   

        $this->assertEquals($c$a $b);   

    }   

    

    public function provider()   

    {   

        return array(   

          array(000),   

          array(011),   

          array(101),   

          array(113)   

        );   

    }   

}  

?>

 

 

结果:
PHPUnit 3.3.4 by Sebastian Bergmann.
…F
Time: 0 seconds
There was 1 failure:
1) testAdd(DataTest) with data set #3 (1, 1, 3)
Failed asserting that matches expected value .
D:\wamp\www\Test\php\unittest\data_provider.php:9

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

…F  表示三个测试成功,一次测试失败.
到此就可以简单的使用PHPUnit了,当然PHPUnit的功能远不止此,测试人员应该好好学习一下.