`
javafenger
  • 浏览: 246725 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

TDD-测试驱动开发的一般原则!

阅读更多

这些年来,我喜欢下面三条简单的规则来描述测试驱动开发:

  1. 除非这能让失败的单元测试通过,否则不允许去编写任何的产品代码。
  2. 只允许编写刚好能够导致失败的单元测试。 (编译失败也属于一种失败)
  3. 只允许编写刚好能够导致一个单元测试失败的产品代码。

对于任何功能,一定要从编写它的单元测试开始;但是到了原则2,你就不能再为那个单元测试写更多内容。只要一出现该单元测试代码编译失败,或是断言失败,你就必须停下来开始编写产品代码;但是到了原则3,你就只能编写产品代码,直到让测试编译成功或通过断言为准。

仔细想想,就会发现如果不是去让一些东西编译或是执行,你就根本没办法去写代码。确实,这正是关键所在。我们做的任何事情(无论是写测试,写产品代码,或是重构),我们都要保持系统能够一直运行。跑通测试的时间间隔应该是以秒或是分钟级的。即使10分钟甚至都太长了。

想了解实际的操作过程,可以看看“保龄球游戏中的Kata”(译注2)一文。

目前有很多程序员,每当他们头一次听到这种技术的时候,会想:“这种做法太愚蠢了!”“这会让我慢下来,这是时间和精力的浪费,让我无法思考,无法设计,它会打乱我的思路。”然而,试想当你走进一个房间,里面都是用这种方式工作的人们,会发生怎样情况。随便一个时间随意找个人,一分钟以前,他们所有的代码都跑通了。

让我再重复一遍:一分钟以前每个人的代码都能跑通!不管你找谁,也不管你何时去找,一分钟以前他们所有的代码都跑通了!

如果你所有的代码自始至终都能跑通,那么你会多长时间用一次调试器?答案是,不会太经常。只要敲几下^Z就能很容易的恢复这些代码到跑通时的状态,然后再试着把前几分钟的代码写一遍即可。而如果你不经常调试,那么会省去多少时间呢?而现在你花在调试上的时间又有多少呢?一旦你有调试过,你又要花上多少时间来修复这些bug呢?如果你能够大大减少这些时间的话,又会如何呢?

好处还不只如此。如果你采用这种方法,那么每一个小时你都会产生好几个测试;每天就有十几个;每个月就几百个;一年下来,你所编写的测试就会有数千个。你可以保留着这些测试而且在任何你希望的时候去运行它们!什么时候运行它们呢?随时!只要你做了更改,就去运行它们!

有些代码已经混乱不堪了,可是我们为何不去清理它们呢?我们担心会破坏它们。但如果我们拥有测试,我们就有理由确信这些代码不会被破坏,或是说我们可以很快的就找到被破坏的地方。如果我们有了这些测试,我们就对代码发生改变无所畏惧。如果我们看到混乱的代码,或是一个不清晰的结构,我们可以毫无顾虑地清理它。因为有了测试,代码重新变得易修改了;因为有了测试,软件重新变“软”了。

好处还不只如此。如果你想要知道如何去调用一个特定的API,就会有一个测试能够告诉你;如果你想要知道如何创建一个特定的对象,就会有个测试能告诉你。你想知道的任何有关这个系统的,都有一个测试能够去示意。这些测试就像是小型的设计文档,小型的代码示例,描述了系统的工作和使用方式。

你是否曾经整合过一个第三方库到你的项目中呢?你拿到一个厚厚的精致的文档手册。在结尾处,有一沓薄薄的示例附录。你会选择哪个去阅读呢?当然是示例了!那就是单元测试啊!它们是这份文档中最有用的部分。它们是如何使用代码的鲜活的例子。它们是极其详细、完全没有歧义的设计文档,相当的正规甚至可以执行,而且不会与产品代码相脱离。

好处还不只如此。如果你曾有过增加单元测试到一个可以工作的系统中的经历,你会发现那一点都不好玩。你很可能会发现你要么必须去改变系统的部分设计,要么就欺骗测试,这是因为你试图去测试的系统并不是基于可测试设计的。例如,你想要测试某个函数f。然而,f调用了另外一个从数据库中删除记录的函数。在你的测试中,你不希望这条记录被删掉,但你有没有办法来阻止它。这样的系统就不是基于可测试设计的系统。

当你遵循TDD的三条规则的时候,你的所有代码天生就可测试!而且另一个能形容“可测试”的词汇就是“可解耦”。为了单独的测试一个模块,你就必须把它解耦。所以TDD强制你去解耦这些模块。确实,如果你遵循这三条规则的话,你会发现你可能比起从前来能做出更多的解藕。这就强制了你去创造更好的,低耦合的设计。

收获了所有的这些好处,这些愚蠢的小规则实际上好像就没那么愚蠢了吧。他们实际上很可能是一些基本而又深刻的原则。确实,在我接触TDD之前我曾做过将近30年的程序员。我不认为曾有过什么人教过我一些基本而又有意义的编程实践。毕竟三十年意味着很多的经验。但当我开始了使用TDD,我就被这项技术的有效性令我震撼也让沉迷其中。我不会再考虑去敲一大堆代码然后指望它们能运行成功。我也不能忍受将一组模块打散,然后希望能够再将他们整合起来并且让它们在能下个礼拜五前运行起来的做法了。在我写程序的时候,每一个决定都由这种让现在开始写的代码能在一分钟后再次执行这样的基本需求所驱使着。

 

译注:

1,TDD,测试驱动开发。

2,Kata,可理解为武功招式,详细解释可参见译者的上篇译文

小注:本篇文章由邓辉先生亲自校正,并给予了很多中肯而深刻的建议,译者在此给予感谢!

 (原文链接网址:http://www.butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd; Robert C. Martin的英文blog网址: http://www.butunclebob.com/ArticleS.UncleBob 

译者注:Robert C. MartinObject Mentor公司总裁,面向对象设计、模式、UML、敏捷方法学和极限编程领域内的资深顾问。他不仅是Jolt获奖图书《敏捷软件开发:原则、模式与实践》(中文版)(《敏捷软件开发》(英文影印版))的作者,还是畅销书Designing Object-Oriented C++ Applications Using the Booch Method的作者。MartinPattern Languages of Program Design 3More C++ Gems的主编,并与James Newkirk合著了XP in Practice。他是国际程序员大会上著名的发言人,并在C++ Report杂志担任过4年的编辑。



分享到:
评论

相关推荐

    TDD 测试驱动开发 文档 详细

    标题中的“TDD测试驱动开发文档详细”表明这是一个关于TDD的详细资料集合,可能涵盖了TDD的理论基础、实践步骤、工具使用等方面。描述中提到的“java TDD测试开发流程”,意味着这些文档专注于Java语言的TDD实践,...

    TDD测试驱动开发

    文件名中的“测试驱动开发TDD培训讲义.ppt”、“TDD_测试驱动开发.ppt”和“测试驱动开发—1.1_测试驱动开发简介.ppt”很可能包含了关于TDD的详细讲解,涵盖了TDD的概念、原则、实践技巧以及如何在实际项目中应用...

    OOCamp--测试驱动开发

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法论,它提倡先编写自动化测试用例,然后再编写满足这些测试用例的最小功能代码。这种开发方式可以提高代码质量,降低维护成本,同时也有助于尽早...

    测试驱动开发(TDD)入门讲解及代码实例

    测试驱动开发(TDD)是极限编程的重要特点,它以不断的测试推动代码的开发,既简化了代码,又保证了软件质量。本文从开发人员使用的角度,介绍了 TDD 优势、原理、过程、原则、测试技术、Tips 等方面。 背景 一个...

    Laravel开发-laravel-tdd-docs

    在 Laravel 框架中,Test-Driven Development(TDD,测试驱动开发)是一种强大的软件开发方法论,它强调先编写测试,然后编写满足这些测试的代码。这种实践有助于确保代码质量、减少错误并促进更好的设计。`laravel-...

    TDD:TDD - 测试驱动开发 - Agile JavaTM_ Crafting Code Wit - Jeff Langr

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,强调在编写实际代码之前先编写测试用例。这种做法确保了软件的质量,并且促进了敏捷开发的原则。《Agile JavaTM: Crafting Code with Test-...

    code kata以及测试驱动开发TDD介绍实用PPT课件.pptx

    本课程主要介绍了 Code Kata 和测试驱动开发(TDD)的概念和实践方法,并对软件设计的基本原则进行了详细的讲解。课程共计 13 页,涵盖了软件设计的九个原则,包括内聚性、松耦合、零重复、封装、可测试性、可读性、...

    敏捷转型-测试驱动开发回顾

    测试驱动开发(TDD)是一种软件开发方法,它强调在编写实际功能代码之前先编写测试用例。这种方法由三个主要步骤组成,通常被称为“六字真言”:变红、变绿、重构。在敏捷开发中,TDD被认为是一种提高代码质量、减少...

    tdd-part1:测试驱动开发-测试用例

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,强调在编写实际代码之前先编写测试用例。这种做法有助于确保代码的质量,因为每个功能或模块都必须通过预先定义好的测试才能被认为是完整的。...

    TDD驱动测试开发培训

    测试驱动开发(TDD)是一种软件开发方法,它要求开发者首先编写失败的单元测试用例,然后再编写足够的代码以使测试通过。接下来,开发者会对代码进行重构以改善设计,同时确保测试依然能够通过。这个过程循环进行,...

    python测试驱动开发

    1. **测试驱动开发(TDD)的概念** - 定义与原则 - TDD在软件开发生命周期中的作用 - 实施TDD的好处与挑战 2. **Python与测试驱动开发** - Python作为TDD的理想语言 - Python中的测试框架:`unittest`与`pytest`...

    java测试源码-tdd-java-ch05-design-my-version:Java测试驱动开发第5章

    【Java测试驱动开发第5章】是关于使用TDD(测试驱动开发)方法在Java环境中进行软件设计的一个章节。TDD是一种敏捷开发实践,强调先编写测试,再编写实现代码,以此来确保代码质量并降低维护成本。在这个章节中,...

    TDD-iOS-swift-4.0.pdf

    根据文件信息,该文件是关于使用Swift 4进行iOS开发的测试驱动开发(TDD)的书籍,书名为《Test-Driven iOS Development with Swift 4 (Third Edition)》。该书的作者是Dominik Hauser博士,他完成物理学博士学业后...

    ses-tdd-exercise-1-template-源码.rar

    标题 "ses-tdd-exercise-1-template-源码.rar" 提示我们这是一个关于软件开发的练习项目,可能涉及测试驱动开发(TDD)的概念。在这个练习中,"template" 指的可能是一个模板项目,用于指导开发者进行TDD实践。源码...

    [测试驱动开发的三项修炼——走出TDD丛林].rar

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,强调在编写实际代码之前先编写测试用例。这种做法有助于确保软件的质量,并且能够及时发现和修复错误。在《测试驱动开发的三项修炼——走出...

    tdd-java-test:测试驱动开发示例

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,强调在编写实际代码之前先编写测试用例。TDD的核心理念是"先写测试,后写代码",以此来驱动功能的设计和实现。在Java环境中,TDD可以帮助...

    测试驱动开发-中文英文.zip

    测试驱动开发(Test-Driven Development,简称TDD)是一种软件开发方法,由Kent Beck在其著作《测试驱动开发:通过实例》中提出并详尽阐述。这种方法主张先编写自动化测试用例,然后再编写满足这些测试的代码,从而...

    tdd-for-web-development-with-django-and-selenium

    ### 测试驱动开发(TDD)在Django与Selenium中的应用 #### 一、测试驱动开发(TDD)概述 测试驱动开发(Test-Driven Development, TDD)是一种软件开发方法论,强调在编写任何功能代码之前先编写测试。这种方法的核心...

    测试驱动开发的3项修炼-走出TDD丛林

    ### 测试驱动开发的三项修炼:走出TDD丛林 #### 一、理解测试驱动开发(TDD) **测试驱动开发**(Test-Driven Development,简称TDD)是一种以测试为先导的开发方法论,它强调在编写任何业务代码之前先编写测试...

    tdd-by-example:尝试肯特·贝克(Kent Beck)关于测试驱动开发的书

    《测试驱动开发:通过实例探索TDD》是著名软件开发者肯特·贝克(Kent Beck)的一本经典著作,书中详细介绍了测试驱动开发(Test-Driven Development,简称TDD)的概念、方法和实践。这本书的核心理念是提倡在编写...

Global site tag (gtag.js) - Google Analytics