Scrum敏捷软件开发之技术实践——测试驱动开发TDD

重复无聊的定义

测试驱动开发,英文全称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技

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

时间: 2024-08-01 22:47:54

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

测试驱动开发TDD(一)TDD的好处及介绍

背景 一个高效的软件开发过程对软件开发人员来说是至关重要的,决定着开发是痛苦的挣扎,还是不断进步的喜悦.国人对软件蓝领的不屑,对繁琐冗长的传统开发过程的不耐,使大多数开发人员无所适从.最近兴起的一些软件开发过程相关的技术,提供一些比较高效.实用的软件过程开发方法.其中比较基础.关键的一个技术就是测试驱动开发(Test-Driven Development).虽然TDD光大于极限编程,但测试驱动开发完全可以单独应用.下面就从开发人员使用的角度进行介绍,使开发人员用最少的代价尽快理解.掌握.应用这种

软件测试方法和技术实践(学习笔记)

网易云课堂:软件测试方法和技术实践 只做了第一节的笔记,后面几节貌似没什么重点... Q:什么是软件测试? A:G.J.Myers:测试是为证明程序有错,通过运行程序发现其中存在的问题. Q:软件测试的对象仅仅是程序么? A:软件=程序+数据+文档 软件包含组件模块.UI. 数据库.系统 Q:什么是全过程的软件测试? A:全过程软件测试包括 [需求审评:需求缺陷   设计审评:设计缺陷  单元与集成测试:代码和接口缺陷 系统测试:系统缺陷    验收测试:其他各种缺陷] Q:发现错误还是发现缺陷

机器学习实践 测试驱动的开发方法——互动出版网

这篇是计算机类的优质预售推荐>>>><机器学习实践 测试驱动的开发方法> 用测试驱动方法开发出可靠.稳定的机器学习算法. 编辑推荐 本书介绍在开发机器学习算法时如何运用测试驱动的方法,捕捉可能扰乱正常分析的错误.这本实践指南从测试驱动开发和机器学习的基本原理讲起,展示了如何将测试驱动开发运用于若干机器学习算法,包括朴素贝叶斯分类器和神经网络. 任何机器学习算法都有一些传统的测试方法,但它们通常都不会考虑编码中的人为错误.借助测试驱动的开发方法,你便不会像其他研究者那样盲

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

2018-2019-2 20175303 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验报告封面 课程:Java程序设计 班级:1753 姓名:柴轩达 学号:20175303 指导教师:娄嘉鹏 实验日期:2019年4月29日-5月2日 实验序号:3 实验名称:敏捷开发与XP实践 实验步骤 敏捷开发与XP实践-1 实验要求 参老师给的链接安装alibaba 插件,解决代码中的规范问题. 在IDEA中使用工具(Code->Reformate Code)把下面代码重新格式化,

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

2018-2019-20175322 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验内容 1.XP基础 2.XP核心实践 3.相关工具 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 2.完成实验.撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等).解决办法(空洞的方法如"查网络"."问

20175333曹雅坤 实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告

20175333曹雅坤 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 敏捷开发与XP实践-1 实验目的与要求: http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECCODESTANDARD 安装alibaba 插件,解决代码中的规范问题. 在IDEA中使用工具(Code->Reformate Cod

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

2018-2019-20175329 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 完成实验.撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等).解决办法(空洞的方法如"查网络"."问同学"."看书"等一律得0分)以及

软件工程 - 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=aladdin https://en.wikipedia.org/wiki/Test-driven_development https://github.com/mjhea0/flaskr-tdd 总结 先写测试,然后写程序pass掉测试,that is 测试驱动开发. TDD usually foll

机器学习实践测试驱动的开发方法pdf

下载地址:网盘下载 内容简介  · · · · · · 本书主要介绍如何将测试驱动开发运用于机器学习算法.每一章都通过示例介绍了机器学习技术能够解决的有关数据的具体问题,以及求解问题和处理数据的方法.具体涵盖了测试驱动的机器学习.机器学习概述.K 近邻分类.朴素贝叶斯分类.隐马尔可夫模型.支持向量机.神经网络.聚类.核岭回归.模型改进与数据提取等内容.通过学习本书,你将能够利用机器学习技术解决涉及数据的现实问题. 作者简介  · · · · · · Matthew Kirk 是Modulus 7