测试驱动的研发和单元测试是确保代码在经过修改和重大调整之后依然能如我们期望的相同工作的最新方法。在本文中,您将学习到如何在模块、数据库和用户界面(UI)层对自己的 PHP 代码进行单元测试。

现在是凌晨 3 点。我们怎样才能知道自己的代码依然在工作呢?

Web 应用程式是 24x7 不间断运行的,因此我的程式是否还在运行这个问题会在晚上一直困扰我。单元测试已帮我对自己的代码建立了足够的信心 —— 这样我就能够安稳地睡个好觉了。

单元测试 是个为代码编写测试用例并自动运行这些测试的框架。测试驱动的研发 是一种单元测试方法,其思想是应该首先编写测试程式,并验证这些测试能够发现错误,然后才开始编写需要通过这些测试的代码。当任何测试都通过时,我们研发的特性也就完成了。这些单元测试的价值是我们能够随时运行他们 —— 在签入代码之前,重大修改之后,或部署到正在运行的系统之后都能够。

PHP 单元测试

对于 PHP 来说,单元测试框架是 PHPUnit2。能够使用 PEAR 命令行作为一个 PEAR 模块来安装这个系统:% pear install PHPUnit2

在安装这个框架之后,能够通过创建派生于 PHPUnit2_Framework_TestCase 的测试类来编写单元测试。

模块单元测试

我发现开始单元测试最好的地方是在应用程式的业务逻辑模块中。我使用了一个简单的例子:这是个对两个数字进行求和的函数。为了开始测试,我们首先编写测试用例,如下所示。


清单 1. TestAdd.php

<?php

            require_once 'Add.php';

            require_once 'PHPUnit2/Framework/TestCase.php';

            class TestAdd extends PHPUnit2_Framework_TestCase

            {

            function test1() { $this->assertTrue( add( 1, 2 ) == 3 ); }

            function test2() { $this->assertTrue( add( 1, 1 ) == 2 ); }

            }

            ?>

            

这个 TestAdd 类有两个方法,都使用了 test 前缀。每个方法都定义了一个测试,这个测试能够和清单 1 相同简单,也能够十分复杂。在本例中,我们在第一个测试中只是简单地断定 1 加 2 等于 3,在第二个测试中是 1 加 1 等于 2。

PHPUnit2 系统定义了 assertTrue() 方法,他用来测试参数中包含的条件值是否为真。然后,我们又编写了 Add.php 模块,最初让他产生错误的结果。


清单 2. Add.php

<?php

            function add( $a, $b ) { return 0; }

            ?>

            

现在运行单元测试时,这两个测试都会失败。


清单 3. 测试失败

% phpunit TestAdd.php

            PHPUnit 2.2.1 by Sebastian Bergmann.

            FF

            Time: 0.0031270980834961

            There were 2 failures:

            1) test1(TestAdd)

            2) test2(TestAdd)

            FAILURES!!!

            Tests run: 2, Failures: 2, Errors: 0, Incomplete Tests: 0.

            

现在我知道这两个测试都能够正常工作了。因此,能够修改 add() 函数来真正地做实际的事情了。

<?php

            function add( $a, $b ) { return $a $b; }

            ?>

            

现在这两个测试都能够通过了。


清单 4. 测试通过

% phpunit TestAdd.php

            PHPUnit 2.2.1 by Sebastian Bergmann.

            ..

            Time: 0.0023679733276367

            OK (2 tests)

            %

            

尽管这个测试驱动研发的例子很简单,但是我们能够从中体会到他的思想。我们首先创建了测试用例,并且有足够多的代码让这个测试运行起来,但是结果是错误的。然后我们验证测试的确是失败的,接着实现了实际的代码使这个测试能够通过。

我发现在实现代码时我会一直不断地添加代码,直到拥有一个覆盖任何代码路径的完整测试为止。在本文的最后,您会看到有关编写什么测试和如何编写这些测试的一些建议。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!