| 一、总览 
                          什么是simpletest? Simpletest的核心是一套建立在测试用例类上的测试框架。这些测试用例类都是继承自测试用例基类,每个测试用例实际上是测试代码。顶层的测试脚本调用run方法按照顺序执行所有用例类。每个测试方法都调用assert的变种函数来判断测试的结果。 下面是一个测试用例的例子: <?php class MyTestCase extends UnitTestCase {     function testLogWroteMessage() 
                          {         $log = &new 
                          Log('my.log');         $log->message('Hello');         $this->assertTrue(file_exists('my.log'));     } } ?> 这些工具是为开发者而写的。测试用php语言写成。用php语言的优势是不用学习新的语言,测试可以马上开始,开发者可以测试任何部分代码。一般所有能被应用程序访问的代码,也能被测试代码访问,如果他们是同一种语言的话。 测试用例最简单的类型是UnitTestCase,这个类包含了所有用于质量、引用、模式匹配的标准测试。这些是绝大多数日常开发的测试所需要的。  Web应用程序的顶级任务不是产生正确的输出,而是生成页面。WebTestCase类用于测试web页面。他仿真了web浏览器对页面的请求,包括cookie、代理、安全连接、验证、表单、frame以及大多数导航元素。有了这个类,开发者能判断页面的信息正确与否。 一个web测试用例的例子: <?php class MySiteTest extends WebTestCase {    function testHomePage() {         $this->get('http://www.my-site.com/index.php');         $this->assertTitle('My Home Page');         $this->clickLink('Contact');         $this->assertTitle('Contact me');         $this->assertPattern('/Email me at/');     }  } ?> 二、单元测试 单元测试用例 下面是一个测试用例的样例: class FileTestCase extends UnitTestCase { }   一般的,测试用例中总是有一些方法,这些方法的名称以”test”开头,这些方法会在run中被自动调用,应该根据实际需要尽可能多的增加测试方法。 例如: require_once('../classes/writer.php');class FileTestCase extends UnitTestCase {    function FileTestCase() {        $this->UnitTestCase('File test');    }     function setUp() {         @unlink('../temp/test.txt');     }      function tearDown() {         @unlink('../temp/test.txt');     }      function testCreation() {         $writer = &new FileWriter('../temp/test.txt');         $writer->write('Hello');         $this->assertTrue(file_exists('../temp/test.txt'), 'File created');     }  } 构造函数是可选的,通常被省略。 在上面的例子中,我们唯一的方法是testCreation函数,用于测试文件是否被Writer对象创建。我们也能在这个方法中放上unlink函数,但是我们将清理临时文件的任务交给了setUp和tearDown。 setUp运行于每个测试方法运行之前,tearDown运行于每个测试方法运行之后。 我们用assert系列函数来判断运行结果。下面是UnitTestCase类的全部assert函数列表: 
                           
                            | assertTrue($x) | Fail if $x is false |   
                            | assertFalse($x) | Fail if $x is true |   
                            | assertNull($x) | Fail if $x is set |   
                            | assertNotNull($x) | Fail if $x not set |   
                            | assertIsA($x, $t) | Fail if $x is not the class or type $t |   
                            | assertNotA($x, $t) | Fail if $x is of the class or type $t |   
                            | assertEqual($x, $y) | Fail if $x == $y is false |   
                            | assertNotEqual($x, $y) | Fail if $x == $y is true |   
                            | assertWithinMargin($x, $y, $m) | Fail if abs($x - $y) < $m is false |   
                            | assertOutsideMargin($x, $y, $m) | Fail if abs($x - $y) < $m is true |   
                            | assertIdentical($x, $y) | Fail if $x == $y is false or a type mismatch |   
                            | assertNotIdentical($x, $y) | Fail if $x == $y is true and types match |   
                            | assertReference($x, $y) | Fail unless $x and $y are the same variable |   
                            | assertClone($x, $y) | Fail unless $x and $y are identical copies |   
                            | assertPattern($p, $x) | Fail unless the regex $p matches $x |   
                            | assertNoPattern($p, $x) | Fail if the regex $p matches $x |   
                            | expectError($x) | Swallows any upcoming matching error |   
                            | assert($e) | Fail on failed expectation object $e |   所有的assert函数能加一个可选的描述作为最后一个参数。这能标识结果。如果省略此函数,将显示默认提示。默认提示字符串也能在自定义字符串中用”%s”来引用,所有判断返回true表示通过,返回false表示失败! 下面是一些例子: $variable = null; $this->assertNull($variable, 'Should be cleared');  …将通过,并且不显示信息。如果你设置了通过的也要显示的设置器,消息将被显示。 $this->assertIdentical(0, false, 'Zero is not false [%s]');  这个函数将失败,当他执行类型检查时,”%s”将被默认的错误消息替换。 $a = 1; $b = $a; $this->assertReference($a, $b);  将失败,因为a是b的副本。 $this->assertPattern('/hello/i', 'Hello world'); 将通过,因为用大小写不敏感匹配,hello包含在Hello world中。 单元测试用例也有一些方便的方法用于调试和扩展用例: 
                           
                            | setUp() | Runs this before each test method |   
                            | tearDown() | Runs this after each test method |   
                            | pass() | Sends a test pass |   
                            | fail() | Sends a test failure |   
                            | error() | Sends an exception event |   
                            | signal($type, $payload) | Sends a user defined message to the test reporter |   
                            | dump($var) | Does a formatted print_r() for quick and 
                              dirty debugging |  继承测试用例 当然附加的测试方法能被加到创建特殊的测试用例,看下例: require_once('simpletest/unit_tester.php');class FileTester extends UnitTestCase {     function FileTester($name = false) {         $this->UnitTestCase($name);      }      function assertFileExists($filename, $message = '%s') {         $this->assertTrue(                  file_exists($filename),                  sprintf($message, 'File [$filename] existence check'));      }  } 这儿,SimpleTest库放在本地目录simpletest中,用你的服务器路径代替它。 为了防止这个用例运行,应该明智的将它标记为abstract。 新的用例现在能将它作为单元测试用例基类,继承于它,看下例: class FileTestCase extends FileTester {    function setUp() {        @unlink('../temp/test.txt');    }     function tearDown() {        @unlink('../temp/test.txt');    }     function testCreation() {        $writer = &new FileWriter('../temp/test.txt');        $writer->write('Hello');        $this->assertFileExists('../temp/test.txt');     } } 如果你想要的测试用例不需要UnitTestCase的一些assert函数,只有你自己的一些基础函数,那么你需要继承于SimpleTestCase,他在simple_test.php中。  运行单个测试用例  一般你很少运行单个测试用例,除非你遇到了一个非常困难的模块。下面是一个运行单个测试用例的例子: <?php     require_once('simpletest/unit_tester.php');    require_once('simpletest/reporter.php');     require_once('../classes/writer.php');       class FileTestCase extends UnitTestCase {        function FileTestCase() {            $this->UnitTestCase('File test');        }     }          $test = &new FileTestCase();      $test->run(new HtmlReporter());  ?> 这个用例将运行,运行结果是0个通过,0个失败,除非你加了测试方法。  |