重复无聊的定义

测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。(来源百度百科)

重复无聊的过程

测试驱动开发的基本过程如下:
  1. 快速新增一个测试(编者注:并非快速)
  2. 运行所有的测试(有时候只需要运行一个或一部分),发现新增的测试不能通过
  3. 做一些小小的改动,尽快地让测试程序可运行,为此可以在程序中使用一些不合情理的方法
  4. 运行所有的测试,并且全部通过
  5. 重构代码,以消除重复设计,优化设计结构
(来源百度百科)

然而来自维基百科上的过程

解释稍有不同,却十分重要

1.Add a test

In test-driven development, each new feature begins with writing a test. To write a test, the developer must clearly understand the feature's specification and requirements. The developer can accomplish this through use cases and user stories to cover the requirements and exception conditions, and can write the test in whatever testing framework is appropriate to the software environment. It could be a modified version of an existing test. This is a differentiating feature of test-driven development versus writing unit tests after the code is written: it makes the developer focus on the requirements before writing the code, a subtle but important difference.

2.Run all tests and see if the new one fails

This validates that the test harness is working correctly, that the new test does not mistakenly pass without requiring any new code, and that the required feature does not already exist. This step also tests the test itself, in the negative: it rules out the possibility that the new test always passes, and therefore is worthless. The new test should also fail for the expected reason. This step increases the developer's confidence that the unit test is testing the correct constraint, and passes only in intended cases.

3.Write some code

The next step is to write some code that causes the test to pass. The new code written at this stage is not perfect and may, for example, pass the test in an inelegant way. That is acceptable because it will be improved and honed in Step 5.

At this point, the only purpose of the written code is to pass the test; no further (and therefore untested) functionality should be predicted nor 'allowed for' at any stage.

4. Run tests

If all test cases now pass, the programmer can be confident that the new code meets the test requirements, and does not break or degrade any existing features. If they do not, the new code must be adjusted until they do.

5. Refactor code

The growing code base must be cleaned up regularly during test-driven development. New code can be moved from where it was convenient for passing a test to where it more logically belongs. Duplication must be removed. Object, class, module, variable and method names should clearly represent their current purpose and use, as extra functionality is added. As features are added, method bodies can get longer and other objects larger. They benefit from being split and their parts carefully named to improve readability and maintainability, which will be increasingly valuable later in the software lifecycle. Inheritance hierarchies may be rearranged to be more logical and helpful, and perhaps to benefit from recognised design patterns. There are specific and general guidelines for refactoring and for creating clean code.[6][7] By continually re-running the test cases throughout each refactoring phase, the developer can be confident that process is not altering any existing functionality.

The concept of removing duplication is an important aspect of any software design. In this case, however, it also applies to the removal of any duplication between the test code and the production code—for example magic numbers or strings repeated in both to make the test pass in Step 3.

Repeat

Starting with another new test, the cycle is then repeated to push forward the functionality. The size of the steps should always be small, with as few as 1 to 10 edits between each test run. If new code does not rapidly satisfy a new test, or other tests fail unexpectedly, the programmer should undo or revert in preference to excessive debugging. Continuous integration helps by providing revertible checkpoints. When using external libraries it is important not to make increments that are so small as to be effectively merely testing the library itself,[4] unless there is some reason to believe that the library is buggy or is not sufficiently feature-complete to serve all the needs of the software under development.

为什么测试驱动开发(TDD)是无价之宝

它能确保系统中所有代码都可以被测试。如果必须写下所有的代码来应付一个失败的测试,那么即使我们什么也不做,至少也使用TDD达到了100%的代码覆盖率。

反对

“我们在开发一个非常复杂的系统,我需要事先做一些架构工作。”

作为一个微观层面的实践,TDD从来就没有说过,不能有效地和少量前期架构考虑结合起来。

“设计:有意的而又是涌现式的”

问题在于,如果可能,在意识上取得平衡之后,还需要事前进行什么程度的架构上的考虑。

“总是先写测试必定会花更多的时间,我没有那么多时间去浪费。”

数据表明,做TDD比不做TDD多花15%的时间(George 和 Williams 2003)。但是,数据

还表明,TDD会带来更少的缺陷。微软的两个研究表明:因为使用TDD,发现的缺陷数下降了

24%和38%(George 和 Williams 2003)。的确,TDD在开始的时候会花费更多的时间,

但是,通过降低缺陷修改和维护的时间,这些时间都能赚回来。

我-曾经的TDD怀疑论者

“做TDD比不做TDD多花15%的时间”

在初级阶段,我曾学习TDD并同时尝试把TDD应用到实际产品开发的过程中,发现实际多花的时间远远不止15%。

因为影响该指数的因素有很多:

  • TDD的过程熟悉
  • 学习如何写合适的测试代码
  • 学习如何做重构
  • 学习如何在特定技术栈下引进合适的测试框架等

笔者认为,这取决于第一次尝试TDD的工程师的成熟度和技术习得能力。对于首次接触此概念的程序员可能需要付出比原来多出100%的时间,

而对处于有成熟TDD体系环境下的程序员,在首次建立TDD的所有测试用例的时间,大概处于10%-40%的范围,具体数值仍然取决于个体成熟度

以及项目本身的特性。然而,我们所增加的时间并不只是建立TDD所有测试用例的时间,维护TDD的所产生的测试用例也是团队所付出的时间成本。

“因为使用TDD,发现的缺陷数下降了24%和38%”

笔者研究过微软的对于TDD研究的两份Paper,本身实验设计有缺陷,不能完全证明缺陷数下降的数值,而只是经验值,环境因素也对此结果有

非常大的影响。但是,随着程序员的成熟度提升,经验上,TDD是能够帮助程序员在交付给QA之前发现更多的问题,或者说能将缺陷扼杀在TDD循

环过程中。

总之

通常情况下,项目本身开发的时间远小于其长期的运营使用时间,期间会随着业务发展不断发生需求变更,随着程序员越来越熟练的使用TDD技

术以及团队敏捷成熟度提高,通过降低缺陷修改和维护的时间,这些时间都能够赚回来。

Scrum敏捷软件开发之技术实践——测试驱动开发TDD的更多相关文章

  1. 使用模拟对象(Mock Object)技术进行测试驱动开发

    敏捷开发 敏捷软件开发又称敏捷开发,是一种从上世纪 90 年代开始引起开发人员注意的新型软件开发方法.和传统瀑布式开发方法对比,敏捷开发强调的是在几周或者几个月很短的时间周期,完成相对较小功能,并交付 ...

  2. 2018-2019-20175205 实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告

    2018-2019-20175205 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>&l ...

  3. 2018-2019-2 20175306实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告

    2018-2019-2 20175306实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验内容 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先 ...

  4. 2018-2019-20175329 实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告

    2018-2019-20175329 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>&l ...

  5. 软件工程 - Test-Driven Development (TDD),测试驱动开发

    参考 https://baike.baidu.com/item/%E6%B5%8B%E8%AF%95%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/3328831?fr=al ...

  6. Django 1.6 的测试驱动开发

    http://www.oschina.net/translate/django-1-6-test-driven-development 测试驱动开发(TDD)是一个迭代的开发周期,强调编写实际代码之前 ...

  7. TDD测试驱动开发

    TDD测试驱动开发 一.概念 TDD故名思意就是用测试的方法驱动开发,简单说就是先写测试代码,再写开发代码.传统的方式是先写代码,再测试,它的开发方式与之正好相反. TDD是极限编程的一个最重要的设计 ...

  8. 【Spring注解驱动开发】聊聊Spring注解驱动开发那些事儿!

    写在前面 今天,面了一个工作5年的小伙伴,面试结果不理想啊!也不是我说,工作5年了,问多线程的知识:就只知道继承Thread类和实现Runnable接口!问Java集合,竟然说HashMap是线程安全 ...

  9. 18. Scrum敏捷软件开发

      1)柯维定律 2)如何组件敏捷团队? 团队5~9个人,Mike带过最多的是14个人.个人建议,别超过10个.否则沟通的成本直线上升.(团队的午餐,两个匹萨就够了). 引入特性团队(针对于传统的组件 ...

随机推荐

  1. android在程序中打开另一个程序

    在开发android应用的时候,在一些情况下要有前置条件,比如这边所说的要启动时要确保别的应用程序服务已经打开  或者在操作中启动别的应用等. 先来一段google上的代码: 1. 已知包名和类名的情 ...

  2. Kafka入门学习(一)

    ====常用开源分布式消息系统 *集群:多台机器组成的系统叫集群. *ActiveMQ还是支持JMS的一种消息中间件. *阿里巴巴metaq,rocketmq都有kafka的影子. *kafka的动态 ...

  3. 第三章 管理程序流(In .net4.5) 之 实现程序流

    1. 概述 本章内容包括 布尔表达式.流控制方式.集合遍历 以及 流跳转. 2. 主要内容 *由于该章内容比较基础,日常用的也很多,故对一些常用的基础内容不再赘述. 2.1 使用布尔表达式 熟悉下列比 ...

  4. Rails学习:create操作 局部模板

    学习Ruby on Rails实战真经 里面说rails4使用了strong parameters, 所以代码这么写:注意不是Event.new(params[:event])了,而是参数是函数返回值 ...

  5. JQuery ----文档处理

    1.append(content|fn) 概述 向每个匹配的元素内部追加内容. 这个操作与对指定的元素执行appendChild方法,将它们添加到文档中的情况类似. 2.appendTo(conten ...

  6. hdu 2647 Reward

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2647 Reward Description Dandelion's uncle is a boss o ...

  7. poj 3061 Subsequence

    题目连接 http://poj.org/problem?id=3061 Subsequence Description A sequence of N positive integers (10 &l ...

  8. 切换两个activity

    下面是一个切换两个activity是过度动画效果实例:(注意里面的overridePendingTransition()方法)Java代码 1. @Override public void onCre ...

  9. iOS 开发者能用上的 10 个 Xcode 插件

    本文由 伯乐在线 - 邢敏 翻译,黄利民 校稿.未经许可,禁止转载! 英文出处:code.tutsplus.com.欢迎加入翻译小组. 1. XcodeColors:给 Xcode 控制台添加颜色 2 ...

  10. 与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。

    今天同学请教我数据库为什么打不开了,打开SQL Server 2008 的 SQL Server Management Studio,输入sa的密码发现,无法登陆数据库?提示以下错误: "在 ...