……为什么人们没有采用
许多没有先编写测试的程序员甚至不知道还可以使用这种方法。如果他们知道,也可能对如何使用它感到迷惑,或者他们可能想知道为什么要这样做。即使他们知道如何去做,并认为它是一种好的想法,但许多人仍然没有先编写测试。

先编写测试需要遵循一定的规程。作为一名程序员,我认为,对于我正在开发的工作,不编写测试可能会更容易些。有时确实如此,但通常只会在短期内是这样。如果我经常不写测试,那么不久会有一堆代码没有经过测试。当编写下一个系统功能部件时,可能会出现不正常现象,问题出在哪里?没有测试,我无法胸有成竹地回答这个问题。即使一切似乎都工作良好,但我不能确保过去在系统中没有出现的问题在以后还不会出现。这种恶性循环就是为什么大多数程序员讨厌测试人员告诉他们代码出现问题的原因。在没有测试的前提下,跟踪错误造成了加班加点以及对工作的不满意。
在我用那种方式向大多数程序员说明这种情况时,他们认为测试驱动的编程是一个不错的想法 — 这之后,他们仍然不使用这种方法。在编写代码前编写测试这种作法意味着,在测试运行并失败之前,不会做工作中真正有趣的部分。不要掉入这个陷阱,否则您以后会付出很多。
难以处理的情形
在人们开始编写测试时,总是会遇到这样一些情形:他们说,“只是没有办法进行测试”。XP 社区的一些人可能毫不含糊地说,不写测试就永远别写代码。您应该努力尝试这么做,但以我个人的经验,有时我发现有些地方我也不能这么做。如果您发现自己处在这种情形,您应该放弃吗?在一定程度上可以。我认为您可以做两件事:
在编写测试前编写代码
在很少情况下,根本不编写测试,放到后面编写
如果发现在尝试先编写测试之后,仍不能先编写测试,那么回到测试中来。我仍然希望进行测试,这样我可以从完整的回归套件中获得信心,但我必须先编写一些代码,然后编写测试。有时我编写了一点代码,然后编写一点测试,这样两者可以一起并进。在少数情况下,我恰好根本想不出如何编写测试。在出现这种情形并且我的结对搭档也想不出法子时,我就问问其他人(例如,另一对搭档),看看他们是否什么聪明点的主意。有时这很管用。但还有一些时候,整个团队都陷入了困境。在那些情况下,必须选择可行性。我可能暂停编码,陷入困境,或者在没有测试的情形下,编写一些代码,到稍后再编写测试。也许代码中出现的第一个错误会使测试什么以及如何测试变得更为明晰。这些是可行的规则。
测试工具和技术
在这世上,几乎每种语言都有一个 xUnit 库。对于 Java 平台,则由 JUnit 担当此任。我个人使用 Eclipse IDE(请参阅参考资料),它极好地集成了 JUnit。Eclipse 是开放源码,有它自己的测试套件,您可以使用它。使用这个合适工具,您可以编写大量好的测试。但有时最好有一些其它帮助。幸运的是,可以利用一些编码技术来更方便地进行测试,甚至可以测试看上去不可测试的事物。可以使用的一些技术包括 ObjectMother 模式、模仿对象(Mock Object)和伪(Sham)对象。
ObjectMother 模式
ObjectMother 模式实际是 Gang of Four Abstract Factory 模式(请参阅参考资料)的实现,它告诉您创建一个工厂对象来给出需要测试对象的实例。例如,假定您正在构建一个处理客户预订讲座的系统。您可能构建一个 ObjectMother 对象,使 Seminar 对象具有不同种特征,您可以用这些特征来测试某些情况。在 Java 语言中,您可能创建 TF_Seminar 对象,它有几个静态工厂方法 — 也许称为 createSomething 或 newSomething。用您对正在创建事物的一些描述代替“something”,譬如 newFullyLoaded,用它来创建具有所有数据成员、并且这些数据成员都已填有已知数据的 Seminar。这样做使得测试数据放在一个地方,从而使代码更干净,更容易重构。在代码中,每当需要完全装入的 Seminar 来进行测试时,可以象清单 7 那样做:
清单 7. ObjectMother 示例