但这个定义看起来还不够好,至少让我们明白起来还有一定的困难。实际上,BDD具有自己特定的“Given,When,Then”行为描述语言,和敏捷的user story极为吻合。所以“Given,When,Then” 行为描述语言才是BDD显著的特征。


TDD在写测试用例时,常常会提出“我们应该先测什么”,然后针对测试的条件来填充代码,而BDD则试图换一种方式去思考问题,即问自己“预期的行为是什么?”,可能会写出结构更好的代码。说到底,BDD更关注客户的需求,通过了解客户的不同行为,对客户的需求有更深刻的理解,从而借助对需求逐渐深入的理解来驱动软件开发。

TDD更重要的价值是其思想,像传统的制造业,一定是先知道产品的质量标准或验收标准之后,才去设计、制造。从这个思想来看,TDD、ATDD和BDD都是一样的。不一样的是其具体的操作方法或实践,我们可以说,ATDD和BDD有一定的进步,但还没有到达完美的地步,还有提升的空间。在未来,首先是如何灵活结合BDD、ATDD和TDD来构成一个测试体系,是一个发展方向;其次,是在BDD、ATDD和TDD根本的、共同的思想基础上,构成一个全新的、更完善的敏捷测试框架。后者的可能性更大。

探索式测试的地位

在过去一两年,在敏捷方法中探索式测试(Exploring Test,ET)也是一个热门话题,甚至有些人想用探索式测试来代替传统的用例测试(case-based test)或脚本测试(scripted  test),走向另一个极端。探索式测试是对用例测试的补充,在非敏捷开发方法中也可以使用。只是在非敏捷开发方法中,有较为严格的需求规范和设计文档,有充分的时间去设计足够的测试用例,探索式测试只是作为一种辅助的手段发现一些隐藏很深的缺陷,并成为一种产品学习的工具以完善测试用例。然而,在敏捷测试中,由于迭代快、需求变化相对频繁,缺乏详细的需求描述文档和足够的设计描述文档,探索式测试发挥更大的作用,甚至在新功能测试中发挥决定性的作用。需要提醒的是,在敏捷测试中,回归测试应该仍然以用例测试为主,可以这样说,回归测试还是百分之百的用例测试。

探索式测试,实际早在1984年由James Bach和Cem Kaner提出来,但为什么直到近几年才比较热呢?这主要得益于敏捷开发方法的兴起,而敏捷开发方法的兴起又得益于互联网应用的迅速扩张。大家都知道,互联网应用越来越普遍,竞争越来越激烈,迫切要求互联网应用产品发布要快,再加上许多互联网产品的开发,都极具创新性、摸着石头过河,其需求不明确,要求开发周期短,频繁发布新的版本,及时获得市场和用户的反馈,不断修正以更好地满足用户的需求。针对被测对象,所掌握的信息不够充分的情况下,探索式测试是一种很有效的测试方法。而且,把测试过程写下来(脚本化)需要时间,在敏捷测试中,时间显得更为珍贵。如果需求变化快,脚本化的测试用例维护成本也过高、甚至是极大的浪费。探索式测试的倡议者还认为,测试执行过程应该是智力活动的过程,这一过程越善于思考、越流畅,我们越有机会发现缺陷。而用例测试方法,有太多的停顿、不够流畅,会破坏这一过程。

在敏捷测试中,当我们没有清晰的可参照文档、没有机会创建测试,我们自然会采用探索式测试。在James A.Whittaker 的《探索式软件测试》出版之后,探索式测试再次被推向高潮,人们觉得有更多成熟的探索方法可以使用,例如:卖点测试法、破坏测试法、地标测试法、收藏家测试法、极限测试法、超模测试法、深巷测试法、配角测试法、强迫症测试法、取消测试法、通宵测试法、混票测试法。

但探索式测试缺乏良好的系统性、复用性,而且有些探索执行终被证明是没有价值的。而我们关注有价值的探索式测试,将它们记录下来,使之成为固定的测试用例,用于将来的(后继的迭代周期)回归测试。回归测试验证已有功能是否正常运行,需要良好的系统性和很高的覆盖率,确保发布产品的质量,而且回归测试是不断重复的,在极有限的时间内完成越来越多的测试任务,这需要自动化执行、高效率执行回归测试。而这一切,依赖于相对稳定的测试用例。概括起来,敏捷测试可以看成:新功能的(手动)探索式测试 + 脚本化(基于测试用例的)自动回归测试。

敏捷测试的自动化

没有自动化,没有持续集成,也没有敏捷。在敏捷测试中自动化测试更加迫切,这一点比较容易理解,每个迭代(如Scrum中的Sprint)都在增加新的功能,而迭代周期的时间相对固定,随着时间的推移,已实现的功能越来越多,这要求越来越多的回归测试在时间相对固定的周期内完成。如果没有自动化测试,这是不可能完成的任务。

在过去一年中,敏捷测试的自动化又发生了哪些变化?如何重构自动化测试脚本以提高产出投入比(ROI)?下面简单讨论一下敏捷自动化测试框架和敏捷测试工具等内容。

敏捷测试对测试工具要求简单、实用,随时可用,而对敏捷测试来说,自动化测试框架更为重要,它将负责集成各种测试工具,包括单元测试工具和验收测试工具等,还负责与持续集成、缺陷管理系统等整个开发环境集成。作为敏捷测试的自动化框架,一般会选择轻量型、开放类型的框架。说到这种类型的框架,可以参考RobotFramework(http://code.google.com/p/robotframework/)。在近一年,其版本发布比较频繁,也日渐成熟。RobotFramework是基于Python开发的、可扩展的框架,所以适用于多种接口的复杂软件(如用户接口、命令行、Web Service、编程接口等)的测试。适合敏捷测试的框架还有Thoughtworks Mingle + Cruise + Twist,它能帮助测试人员和开发人员敏捷项目管理和协同工作、持续集成、测试自动化,允许使用BDD开发模式和Groovy动态语言来编写测试脚本,包括手动和自动方式来创建可复用的自动化测试脚本,并结合测试领域特定语言(DSL)实现自动化测试。无论是RobotFramework,还是Twist,它们都支持Selenium 2.0,这也反映了Selenium在敏捷自动化测试中的重要地位。当然,敏捷测试也可以采用类似Selenium 2.0+ WebDriver +PushtoTest那样的组合框架。

敏捷测试工具很多,但对敏捷测试来说,我们更要关注能够适应ATDD或BDD的测试工具,如Cucumber、RSpec、NBehave /CBehave /JBehave、EasyB、JDave等。也可以结合先前熟悉的测试工具开展工作,例如用自己熟悉的WatiN来结合SpecFlow 完成BDD模式的自动化测试。采用传统的微软Visual Studio也是可以的,因为在其 2010版本中,增强了对敏捷测试的支持,包括:

发布了Scrum流程模板Visual Studio Scrum 1.0;
支持“测试优先”的开发,支持ATDD;
TDD的插件TestDriven.NET。
敏捷测试管理

基于敏捷测试的管理,更多体现了基于需求测试和基于风险测试的平衡。对于新功能测试,不仅采用探索式测试,还要考虑基于需求的测试方法,借助类似BenderRBT这样的工具,进行需求的因果分析,建立其判定表并进行优化,从而建立非常高效的测试用例,使敏捷测试跟上开发的节奏成为可能。但整个测试周期,包括跨迭代周期的回归测试,都需要对测试风险进行有效的评估,在效率和质量上达到平衡,以保证所发布的产品的质量。

敏捷测试的管理,一定不要急躁、不要急于求成,要循序渐进获得改进,特别是从相对传统的测试方法转型到敏捷测试的团队来说,更要逐渐转型,如同敏捷方法本身所追求的“小步快跑”式迭代,这种转型本身也应被视为迭代过程,而不是突然某个早上,一切都变了。在敏捷测试管理中,不要试图通过一个迭代解决所碰到的各种问题,而是一个迭代只解决一两个问题,随着时间的推移,踏踏实实地、逐步地解决各个问题,即进入一个良性的循环,终解决各种问题,使团队转型成功,无论在测试效率和质量上获得质的飞跃。

在敏捷测试管理中,尽管有比较多的原则要支持,例如“以人为本、为客户创造价值、面对面的沟通、简单化、响应变化和享受乐趣”等,但重要的是以下几个方面。

持续的质量反馈:在整个开发过程中,持续关注质量,关注用户需求,发现任何阶段性成果的问题,持续向产品经理、开发人员等提供质量反馈。
持续改进测试方法,不断学习新方法和提高测试技术能力,不仅和开发人员保持技术同步,而且团队成员能力保持同步成长,想方设法把工作做到。
让团队具有很高的自我组织能力,每个成员都积极主动工作,自己能够解决自己的问题。
让我们享受敏捷测试的乐趣,享受成功!