PHP测试驱动开发介绍(2)

发表于:2012-03-14来源:译言网作者:子非鱼.点击数: 标签:PHP;测试驱动开发
就象我们在前一个测试里面做的一样,让我们设法使这个测试通过。为了达到这点,我们必须提供bite()方法,由于我们的测试定义了bite()方法需要如何工作

returns_match_fail_thumb.jpg

  就象我们在前一个测试里面做的一样,让我们设法使这个测试通过。为了达到这点,我们必须提供bite()方法,由于我们的测试定义了bite()方法需要如何工作,我们只需要开发它,不再需要思考它应该怎么样。这个是TDD的另一个核心概念:测试定义了代码行为。

  下面的bite()方法可以使得测试通过:

  function bite($needle, $haystack) {

  if(preg_match($needle, $haystack, $match)) {

  return $match['0'];

  }

  }

  在你的Biter类增加bite()方法,然后再次运行测试。现在应该通过了,产生了下面的画面:

returns_match_success_thumb.jpg

  让我们重温一下刚才我们所做的。我们没有立刻建立bite()方法,我们先为此创建了一个测试,在那之后我们再提供bite()方法。这个就是TDD提倡的:先测试,后开发。

  移除匹配的部分

  我们现在还没有完全完成,因为我们的Biter类有第二个需求:它需要把匹配的部分从原始的字符串中移除。为此让我们再写一个测试:

  function testPatternMatchIsRemovedFromHaystack() {

  $biter =& new Biter;

  $haystack = 'foobar';

  $biter->bite('/foo/', $haystack);

  $this->assertEqual($haystack, 'bar', 'Removed matched part [%s]');

  }

  我们还是使用assertEqual()方法去断言两个变量完全相同,只是这次我们是去检查匹配部分是否已经被移除。

  运行上面的测试,将得到下面的输出:

removed_fail_thumb.jpg

  现在我们必须使得这个测试通过。这个做起来很简单,不过假设我们不写这个测试,而是通过修改其他测试来让这个测试通过,这样可能可以少些测试代码。怎么样,听起来不错?其实是错误的!

  永远不能为了让某一个测试更容易通过而去修改其他的测试!

  哪些其他的测试可能是为了特定需求的结果创建的。你实际运行的脚本可能会依赖于那些测试所通过的特定函数。如果你开始修改其他的测试,你就会失去TDD的所有优势。这就是为什么你永远不能为了更容易通过某个测试而去修改其他测试的原因。

  让我们回到我们的Biter类。我们如何能让这个测试通过?我们必须修改传递进来的字符串,就好像我们处理通过引用的方式传递的参数。修改过的bite()方法看上去象下面这样:

  function bite($needle, &$haystack) {

  if(preg_match($needle, $haystack, $match)) {

  $haystack = str_replace($match['0'], '', $haystack);

  return $match['0'];

  }

  }

  把它放入你的Biter类,然后运行测试。你看到什么?全部都是绿色!

removed_success_thumb.jpg

  现在我们满足了Biter类的所有需求,我们可以开始做我们的脚本里面的其他类,开发起来和我们开发Biter类一样。同时你还能得到另一个好处,就是以后你可以再运行Biter类的测试以便确认它的功能依然正确(这将有效的避免开发过程中偶然的错误修改)。

  结论

  本文中我演示了测试驱动开发如何工作。我们只是构造了一个真实的简单的类,它非常容易去使用TDD方法,不过做为介绍还是不错的选择。

  值得注意的是TDD需要主要焦点的转移,因此它很难推行,它使得开发过程完全不同以往。我可以给出的最好建议是坚持尝试TDD,最终你会迷恋它。一旦习惯了,你再也不会用其他的方法。

  如果你想了解文中的示例项目或者想得到更多的示例,可以看看SitePoint 论坛的相关讨论。非常感谢Noel Darlow使得本文得以呈现,并且提供了本文的大部分示例和信息。

  如果你对本文有任何问题和建议,欢迎在PHPit论坛与我们讨论。

原文转自:http://www.ltesting.net