是的,现在肯定有读者会这样说了:“我只在产品发品之前写测试。”有些人可能会窃笑,对质量保证部门说三道四。还有一些人作为项目经理可能会添油加醋地说:“我们可不会浪费时间写测试代码;我们还得写真正的代码呢。”那么,采用TDD到底是什么意思呢?
TDD产生于敏捷开发运动,特别是极限编程(extreme programming,XP),而且TDD正是XP的一个核心原则。推崇TDD的人认为,不应该完成开发之后再写测试,这通常只是“马后炮”,而应当在写代码之前先写测试。测试本质上相当于设计文档,而不是花大量时间去摆弄一个复杂的图形化工具,你要直接在代码中“拟画”一个类。开始时先为一些小功能块编写测试。在有些语言下,你写的测试甚至不能编译,因为所引用的类尚不存在。一旦建立了测试,就可以运行这个测试(当然,此时运行测试会失败)。然后再编写最少量的代码,以便测试通过。接下来再重构代码,并增加更多的测试。
通常可以使用测试框架来帮助编写自动化测试。最著名的框架是JUnit,不过现在已经有很多xUnit项目,可以简化在各种语言下测试的创建。一般地,这些框架都建立在断言(assert)基础上。开发人员编写测试方法,将调用方法的实际结果与期望结果进行比较。当然,可以人工地检查一个日志文件或用户界面来完成这些比较,但是,用计算机完成数据比较不仅速度快,也更准确。另外,就算是让计算机把同样的测试运行上1500次,它们也不会嫌烦,如果是人可做不到这一点。
有了JUnit和其他测试框架,编写和运行测试变得相当简单。这就能鼓励开发人员创建大量测试(往往能更完备地覆盖各种测试情况),而且会乐于经常运行这些测试(可以更快地帮助开发人员找到bug)。在许多情况下,如果项目中采用了TDD,测试代码往往与生产代码一样多!
使用TDD可以带来许多重要的好处:
提供明确的目标:你很清楚,一旦结束(也就是一旦测试通过),你的工作就完成了(假设你的测试写得很好)。测试会为代码建立一个自然的边界,使你把重点集中在当前任务上。一旦测试通过,就有确切的证据证明你的代码能工作。相对于人工地测试用户界面或者比较日志文件中的结果,在一个xUnit框架中运行自动化测试,速度要快几个数量级。大多数xUnit测试的运行只需几微秒,而且大多数采用TDD的人都会一天运行数次测试。在许多开发小组中,将代码签入源代码树之前,代码必须成功地通过测试。
提供文档:你是不是经常遇到看不懂的代码?这些代码可能没有任何文档说明,而且开发代码的人可能早就走了(或者度假去了)。当然,看到这种代码的时间往往也很不合时宜,可能是凌晨3点,也可能有位副总在你旁边大声催促着赶快解决昨天的问题,这样要想花些时间来明白原作者的意图就更困难了。我们见过一些好的单元测试文档,它们会指出系统要做什么。测试就像原开发人员留下的记号,可以展示他们的类具体是怎么工作的。
改善设计:编写测试能改善设计。测试有助于你从界面的角度思考,测试框架也是代码的客户。测试能让你考虑得更简单。如果你确实遵循了“尽量简单而且行之有效”的原则,就不会写出篇幅达几页的复杂算法。要测试的代码通常依赖性更低,而且相互之间没有紧密的联系,因为这样测试起来更容易。当然,还有一个额外的作用,修改起来也会更容易!
鼓励重构:利用一套健壮的测试集,你能根据需要进行重构。你是不是经常遇到一些不知是否该修改的代码?种种顾虑让你行动迟缓,过于保守,因为你不能保证所做的修改会不会破坏系统。如果有一套好的单元测试集,就能放心地进行重构,同时能保证你的代码依然简洁。
提高速度:编写这么多测试会不会使开发速度减慢呢?人们经常会以速度(或开发开销)作为反对进行TDD和使用xUnit框架的理由。所有新的工具都会有学习曲线,但是一旦开发人员适应了他们选择的框架(通常只需很短的时间),开发速度实际上会加快。一个完备的单元测试集提供了一种方法对系统完成回归测试,这说明,增加一个新特性之后,你不必因为怀疑它会不会破坏原系统而寝食难安。
提供反馈:单元测试还有一个经常被忽略的优点,即开发的节奏。尽管看上去好像无关紧要,但通过测试之后你会有一种完成任务的成就感!你不会成天地修改代码而没有任何反馈,这种测试—代码—测试的方法会鼓励你动作幅度小一些,通常修改一次代码的时间仅几分钟而已。这样你不会一下子看到冒出一大堆的新特性,而只是让代码基一次前进一小步。
从我们的经验看,测试是会传染的,你可能会慢慢上瘾。一开始,许多开发人员都心存疑虑,但最终几乎每个开发人员都迷上了运行测试后的绿条。测试第一次“抓住”bug或者增加一个新特性,只需几分钟而不是几个小时,往往就是在这样一些时候,开发人员会欣喜地认识到测试确实很有意义。
分享到:
相关推荐
是的,现在肯定有读者会这样说了:“我只在产品发品之前写测试。”有些人可能会窃笑,对质量保证部门说三道四。还有一些人作为项目经理可能会添油加醋地说:“我们可不会浪费时间写测试代码;我们还得写真正的代码呢...
1. **早期测试**:敏捷测试强调尽早开始测试,甚至采用测试先行(Test-First)的方式,如单元测试和集成测试。这是因为缺陷的潜在影响会随着时间的推移呈指数级增长。通过提前测试,可以尽早发现和修复问题,减少...
### 白盒测试方法介绍 #### 一、背景与范围 **1.1 白盒测试的范围** 白盒测试是软件质量保证体系中的一个重要组成部分,它主要关注于软件内部结构和逻辑流程的验证。与黑盒测试不同,白盒测试更侧重于对可见源...
### 第4代白盒测试方法介绍—理论篇 #### 一、背景 ##### 1.1 白盒测试的范围 白盒测试是软件工程中的一种测试策略,它基于对程序内部结构的理解来设计测试用例。传统的白盒测试主要关注源代码级别的测试,包括...
本文首先对敏捷开发方法的基本原理和特点进行了概述,并在此基础上介绍了敏捷软件方法的概念及其与传统软件开发方法的区别。结合当前行业实际应用情况,从功能特点、优缺点、适用场景等方面综合对比了几种常见的敏捷...
1. **测试先行**:首先介绍TDD的基本原则,即“红-绿-重构”循环。"红"代表编写一个失败的测试;"绿"是编写足够的代码使测试通过;"重构"是优化代码结构,保持简洁性。 2. **JUnit框架**:作为Java中最常用的单元...
因为测试先行,开发者必须思考如何设计接口以便于测试,这往往导致更清晰、更模块化的代码结构。TTD也有助于降低维护成本,因为有完整的测试套件作为安全网,当需要修改代码时,可以迅速检查是否引入了新的错误。 ...
XP强调测试先行,旨在尽可能减少未来可能遇到的问题。XP适用于小型团队(最多十人),成员间可以面对面交流。 **过程**:XP包含十二种最佳实践,包括计划游戏、小型发布、系统隐喻、简单设计、测试驱动开发、重构、...
对于敏捷测试,可定义如下: 项目中使用敏捷技术的相关测试实践,开发作为测试的顾客,强调测试先行的设计理念。在敏捷开发中,测试被整合到整个开发的生命周期中。 敏捷测试 敏捷将被越来越多的人所接受,...
对于敏捷测试,可定义如下:项目中使用敏捷技术的相关测试实践,开发作为测试的顾客,强调测试先行的设计理念。在敏捷开发中,测试被整合到整个开发的生命周期中。敏捷测试敏捷将被越来越多的人所接受,这很容易理解...
此外,论文可能还会涉及敏捷开发中的测试实践,比如持续集成(CI)和持续部署(CD),以及TDD(测试驱动开发)和BDD(行为驱动开发)等测试先行的开发模式。这些方法强调将测试融入到整个开发流程中,从而尽早发现...
极限编程是一套实践导向的敏捷方法,其中包括测试先行、持续集成、结对编程等核心实践。在Java开发中,这些实践可以提高代码质量,减少错误,并促进团队间的沟通。 5. **Kanban方法** Kanban强调可视化工作流程,...
8. **自动化测试**:敏捷开发强调“测试先行”,使用自动化测试工具如JUnit、TestNG来编写单元测试和集成测试,确保软件质量。 9. **技术债务**:随着开发的推进,为了快速交付可能会积累一些欠佳的设计或代码,这...
TDD(测试驱动开发)和BDD(行为驱动开发)强调编写测试先行的代码,以测试来定义软件的功能和行为。敏捷测试则注重快速反馈和迭代改进。 最后,质量管理工具,如JIRA、TestRail,可以协助团队管理测试用例、缺陷...
- **测试驱动开发(TDD)**:编写测试用例先行,再编写满足测试的代码。 - **重构**:改进代码结构,保持代码的简洁性和可维护性。 【工具】 在敏捷开发中,工具起到支持和自动化工作流程的作用。例如,Jazz 是IBM...
3. XP:注重编码和测试实践,如对编程、测试先行、结对编程、持续集成等。 四、敏捷实践 1. 用户故事:以用户为中心的简短描述,代表软件功能或用户需求。 2. 任务板:展示项目状态,帮助团队成员了解任务分配和...
同时,极限编程(XP)提出了测试先行的原则,进一步强调了测试在软件开发中的地位。 进入21世纪,随着互联网和移动设备的爆发式增长,软件测试面临更大规模和多样性的挑战。云计算和大数据时代,分布式系统测试、...
- XP(极限编程)实践:测试先行,每个小功能完成后立即进行测试。 9. **移动应用测试**: - 兼容性测试:在不同的设备、操作系统版本、网络环境下进行测试。 - UI测试:检查移动应用的界面设计、布局、用户体验...