技术开发 频道

测试驱动的编程

【IT168 技术文章】

    测试驱动的编程是 XP 困扰程序员的一个方面。对于测试驱动的编程意味着什么以及如何去做,大多数人都做出了不正确的假设。这个月,XP 方面的讲师兼 Java 开发人员 Roy Miller 谈论了测试驱动的编程是什么,它为什么可以使程序员的生产力和质量发生巨大变化,以及编写测试的原理。
    
    最近 50 年来,测试一直被视为项目结束时要做的事。当然,可以在项目进行之中结合测试,测试通常并不是在所有编码工作结束后才开始,而是一般在稍后阶段进行测试。然而,XP 的提倡者建议完全逆转这个模型。作为一名程序员,应该在编写代码之前编写测试,然后只编写足以让测试通过的代码即可。这样做将有助于使您的系统尽可能的简单。

    先编写测试

    XP 涉及两种测试:程序员测试和客户测试。测试驱动的编程(也称为测试为先编程)最常指第一种测试,至少我使用这个术语时是这样。测试驱动的编程是让程序员测试(即单元测试 — 重申一下,只是换用一个术语)决定您所编写的代码。这意味着您必须在编写代码之前进行测试。测试指出您需要编写的代码,从而也决定了您要编写的代码。您只需编写足够通过测试的代码即可 — 不用多,也不用少。XP 规则很简单:如果不进行程序员测试,则您不知道要编写什么代码,所以您不会去编写任何代码。

    如何先编写测试

    整个理论很棒,但如何先编写测试呢?首先,我推荐您阅读 Kent Beck 撰写的 Test-Driven Development: By Example(请参阅参考资料)一书,里面列举了一个详尽的贯穿于整本书的示例。该书不仅讲述了如何编写测试和让这些测试来驱动您的代码的原理,而且还讲述了测试驱动的编程为什么是一种好的编程方法。这里我将举一个简单的例子,让您体会一下我正在讲什么。

   测试驱动 vs. 先测试

    我喜欢用“测试驱动”这个术语,而不喜欢用“先测试”这个术语,因为先测试强调了在编写代码前编写程序员测试这个原理。这些原理很重要,但真正的力量在于测试驱动所隐含的想法和编程习惯的改变。“测试驱动的编程”这一更贴切的术语包含两种测试,它指出 XP 团队强调让测试驱动他们所要做的一切这一方式。
 

    假定我正在编写包含 Person 对象的系统。我希望在我问每个 Person 时,他/她能告诉我其年龄(作为整数)。即使我还没有编写一丁点代码,但也该编写测试了。“什么?”,您可能会说,“我甚至不知道在测试什么,怎么编写测试?”答案很简单,您的确知道您在测试什么,只是不知道您所了解的内容,因为您不习惯按这样的方式进行思考。这就是我的意思。

    

    您确实还没有任何代码,但您脑海中应有 Person 对象的雏形。Person 对象上应该有一个方法,该方法可以用整数形式返回年龄。因为我最常使用 Java 语言,所以我用 JUnit 来编写程序员测试。清单 1 显示了我为 Person 对象编写的 JUnit 测试:

    清单 1. 用于 Person 对象的 JUnit 测试

    
    首先,让我向那些不熟悉 JUnit 的人讲述一些浅显的原理。TestCase 类是您将最常使用的类。您只是写了一个测试类(在该示例是 TC_Person),它是 TestCase 的子类。(注:在 JUnit 3.8.1 中,可以有也可以没有接受 String 的构造函数,但由于我几乎所有的 Java 开发都在 Eclipse IDE(请参阅参考资料)中完成,Eclipse IDE 免费向我提供了这个构造函数,所以我就把它保留在这里了。)一旦创建好测试类之后,测试方法中要有实际的动作。这些方法都恰如其分地用前缀 test 开头(它们必须是 public,并且返回 void)。当运行测试时,JUnit:

    . 内省测试类,并执行每个以“test”开头的方法
    . 在执行每个测试方法之前执行 setUp() 方法
    . 在执行每个测试方法之后执行 tearDown() 方法

    在该示例中,setUp() 方法中没有太多要执行的语句。它只是实例化 Person(我用这个方法是让您觉得这个测试案例看上去很“完整”)。这意味着,如果这里有 20 个测试方法,则每个测试方法都以一个新的 Person 实例开始。tearDown() 中不做任何事情,所以现在它是空的。值得强调的一点,您不需要 setUp() 或 tearDown();我通常直到编写第二个或第三个测试方法,并确定了这些方法都共享某些公共的设置或销毁活动时,才创建它们。

0
相关文章