Gojko Adzic 是《实例化需求》(Specification by Example)一书的作者, 在该书中他给出了一些建议和原则,帮助大家在软件开发项目中采用实例化需求去创建活文档。实例化需求是一组方法,它以一种对开发团队有所帮助的方式(理想情况下表现为可执行的测试)描述计算机系统的功能和行为,让不懂技术的利益相关者也可以理解,即使客户的需求在不断变化,它也具有很好的可维护性,可以保持需求的相关性。
该书拥有众多的例子和建议,其中的 50 多个案例分析验证了不同的团队和组织通过采用该方法取得了不同程度的成功。作者并没有掩饰在引进该方法时所面临的挑战,通过分析那些失败案例所具有的模式和范例,给出了一些避免失败的建议。
作者不仅通过案例分析和举例辨识出团队在引进实例化需求时可能面临的一些常见挑战和问题,而且还提供了具体的建议用于解决这些问题。
尽管该书中所举的大部分例子和案例分析,涉及的是一些采用敏捷开发的团队和组织,但是作者也指出了一个重要观点,这些方法并非局限或依赖于敏捷方法。
该书讲到了测试自动化的价值,并给出了实现自动化方面的建议,但是作者没有深入探究一些可用的工具及其如何配置它们。不过配套的网站提供了一些资源,包括书籍、开源和商业软件的链接、一些文章的链接、视频教程以及演示文稿.
在 Adzic 自己的网站上,他介绍了该书的几个主要思想:
实例化需求是一组过程模式,可以协助软件产品的变更,确保有效地交付正确的产品。 这里所说的正确产品,指的是该软件能满足客户或企业用户提出的商业需求,或者能达成预定的商业目标;同时它要具备一定的灵活性,未来能以相对平稳的投入接受后续改进。
他描述了该过程的多个步骤用以获得需求,并将其转化成一份“活文档“:
- 从目标中获取范围
- 用实例进行描述
- 精炼需求说明
- 自动化验证,无须改变需求说明
- 频繁验证
- 演进出一个文档系统
Gojko 说:
自动化的实例化需求,如果仍以自然语言表达,并且团队的所有成员都可以轻易获取到,那这实际上就形成了一份可执行的需求说明。
“活文档”是实例化需求的最终产物。为了建立起活文档系统,很多团队最终都为需求说明和测试设计了一门领域相关的语言。
出版商为 InfoQ 的读者制作了一个示例章节,可以在这里找到。
作者还在amazon.com 和amazon.co.uk 上进行“ A-B 测试”的对比,并为协助测试者提供一份海报。
最近 InfoQ 的 Shane Hastie 访问了该书的作者:
InfoQ:请你简单介绍一下你自己,还有是什么启发了你写《实例化需求》呢?
Gojko:我是一个顾问,主要与致力于提高软件质量和以迭代为交付模式的团队合作。过去的 5、6 年时间里,我一直在关注敏捷验收测试和行为驱动开发上,而实例化需求是一个很自然的延续。有两点启发了我写这本新书。其中一个是 Tom Gilb 在 2009 敏捷测试日演讲时宣传敏捷并不实用,而且没有数据能证明敏捷如大多数描写和演示它的人说得那样好。另外一个是一篇2009 年在InfoQ 上发表的文章,其中问到是否真有人在敏捷过程中实现了自动化验收测试,还是说该想法只是一个理论上的提议。在那时,我已经目睹过该过程在一些环境下获得了很大的成功,我无法理解这些针对敏捷的怀疑和否定,所以我决定开始收集真实的故事,而不是自我感觉,用以展示给大家确实有人,而且是很多人,已经通过实践该过程从中获得了很大的益处。
InfoQ:编写这本书的目的是为了解决哪些问题?
Gojko:在软件开发社区中,人们对于实例化需求、验收测试驱动开发以及行为驱动开发,确实有不少误解。五年前,我在各种会议中遇见的很多人都从没听说过这些概念。现在大部分我见过的人都听说过它们, 但还是只有极少数人在他们的过程中成功地实施了这些想法。大多数的失败主要是由于那些常见误解造成的。在本书中,我介绍了那些成功团队在他们的过程中实施成功的 7 个关键模式,还有很多从 50 个不同背景的项目经验中获取的窍门和应该避免的注意点。我希望这些知识能够帮助问题团队找出他们自己的典型障碍,排除他们,并提高他们的交付过程。
InfoQ:在该书中,很多经常提到的概念和想法就是大家所说的验收测试驱动开发(ATDD)或者行为驱动开发(BDD),为什么你要提出新的术语实例化需求,而不是使用它们两个?
Gojko:这个术语的负面看法最少。在编写本书的时候,我遇到的一个很大的问题就是如何将来自不同团队的知识以一个统一的概念展现给大家,同时我也意识到作为一个社区我们在这整件事情上采用了完全错误的言词。我们使用技术术语为其命名,却造成了商业用户的困惑,以至于很多想让他们参与进来的想法都失败了。而且我们在命名各种软件过程的工件时也很少会有一致性,这造成了更多的困惑。由此我决定这本书的目标就是要推广一套术语,帮助人们在脑袋里建立起正确的心理图像,让团队可以避免那些常见的陷阱和误解。一个主要的问题是在整个开发过程中,团队过分侧重于测试的方面,将整件事情理解成只是一个测试活动。这就是为什么我不想使用 ATDD 的原因。而 BDD 则是一个还没有精确定义的方法论。取决于你讨论的对象,它可能包括也可能不包括基于拉动式的工作模式,从外到内的设计之类的事情。使用实例作为功能的需求说明,并基于那些实例进行自动化测试是 BDD 的核心支柱,但是它可能不止这些。我们很可能要等 Dan North 写一本关于 BDD 的书去将其明确说明。我希望这本书就是一组具体的实践方法,可以运用在不同的方法论中,就像我曾访问过的那些使用 XP、Scrum、Kanban 及其他方法的团队。
InfoQ:这本书的目标群体是谁呢?
Gojko:所有想交付高质量软件的人。我努力让这本书变的与技术无关,并能让多种不同角色的人员都可以理解,高质量的过程和产品源于整体观和协作:没有单一群体能够独自将其交付。产品经理、业务分析员、测试人员、开发人员以及项目经理都能够平等地从中获益。
InfoQ:你很明确地指出你不会深入到任何一款特定工具的细节中,但是显然,想要有效地将你的想法付诸实践,就需要对相关工具有一个全面的理解。你能给读者一些在工具使用上的建议吗?
Gojko: 工具自动化过程,他们能让过程走得更快。如果你的过程有问题,自动化只会让问题更加突出。我曾错误得认为一个工具可以尽早将问题解决,结果却遭到了惨痛的失败。当我意识到团队协作是我们过去所忽略的时,这一想法促使了我开始编写我的第一本书。很多我为编写《实例化需求》采访过的团队也犯过同样的错误,而这也确实是我在各种 会议中参与讨论时大家提到的一个常见问题。我给读者的建议是首先要完善过程,然后将其自动化以使其运行得更平稳。一旦拥有了良好的过程,一个好的工具将会使其发挥最大的作用。
InfoQ:你使用“活文档”的概念来描述实例化需求的产物,这个概念同传统的文档或用户故事卡等轻量级的敏捷文档有什么区别呢?
Gojko:故事卡本意并不会长期保存。在做短期的优先级排列和计划时它们非常有用。但是当一个故事完成六个月后,如果你需要了解系统时,这些卡片却不会有太大的帮助。而传统的文档又很容易过期。把程序源代码当作唯一可靠的资源用以了解系统的功能,会导致信息瓶颈和黑洞,从长期来看,这正是编写良好的实例化需求的作用。由于这些需求的验证通过验收测试自动化了,并经常被执行,所以我们可以相信系统的行为符合这些测试所指定的功能。或者从另外一个角度来讲,这些文档实时追踪着系统的功能。一个编写良好的实例化需求,应该简单易懂,并容易获取,可以帮助我们消除那些信息瓶颈。
我曾工作过的许多大公司,因为没有一个可靠的文档系统,不仅让软件交付团队面临着很大的问题,而且更重要的是它在商业上也会造成很大程度的损失。通过创建和维护一份可靠和可维护的业务流程文档,活文档可以为 IT 团队带来额外的商业价值。
InfoQ:你对于那些想要实施这种方法的团队有什么建议吗,为了确保他们已经准备好去做这些改变,他们要做些什么呢?
Gojko:所有的事情都是有前后关系的。每个团队都需要知道他们的问题是什么,然后利用书上的想法作为启发来解决这些问题。一个好的对策就是让整个团队能够对他们在交付高质量产品所面临的首要问题上达到一致,并致力去解决它,然后接着解决下一个问题。这是个非常有效的改进策略,因为它提出了一个共同的目标,可以减少抵制心理,并给管理层提供了一个令人信服的理由去支持改变(因为团队正在解决他们的首要问题)。
InfoQ:为了采用这种方法,团队和组织需要做出的最大改变是什么?
Gojko:再强调下,这是有前后关系的。通常情况下最大的改变就是文化,从涂鸦墙上什么任务应该要抛弃掉、什么责任需要被转移的传统方式转变到一个更具协作性和整体性的软件交付方式上。实例化需求需要团队不同角色间紧密的合作,并共同支持团队向一个更为协作的环境转变。
InfoQ:你见过的最常见的错误是什么,团队应该怎样去避免他们呢?
Gojko:把精力放在一个特定工具上是很多人都会犯的一个严重错误,因为这并不会提高协作能力,反而会造成更多的问题。还有一个常见的问题就是实施这一过程时单纯从测试角度去考虑问题,工件变成了过度饱和的数据和测试用例的组合爆炸,这让实例化需求失去了作为沟通工具的作用。第三个常见的问题就是需求说明的错误设计,利用技术语言或脚本去描述某个功能是怎么被测试的,而不是去描述系统应该怎么工作。
这会造成后期维护的困难。
为了避免这些问题,团队必须专注于价值、协作和改进沟通,发展出一套通用的语言,并在所有工件中使用一致。
InfoQ:你能给团队什么建议来帮助他们维持这种改变,并保持活文档的“活性”呢?
Gojko:团队应该意识到随着知识领域的发展和商业机会的改变,项目语言也会随着时间的推移而演进。这会影响实例化需求以及活文档系统组织和解释事情的方式。为了获得长期的受益,团队必须保持活文档系统的一致性。这是一个更为广泛的话题,包括领域驱动设计、统一语言以及如何一致地使用它去支持对称的改变:一个业务功能上的小改动将通过软件和文档中的小变动来体现。如果我们让这些模式慢慢分开,那么软件很快就会变为古董,到了某一时刻,很多人就会放弃更改而决定重写。但是如果这些模式能够协调一致,我们完全可以避免这种遗留陷阱。因此,活文档系统的确可以更早地提醒我们这类问题,我认为团队应该要明白保持文档活性的同时可以确保相关软件的活性。
InfoQ:那些采用实例化需求的团队和组织是如何从中受益的呢?
Gojko:大体上可分为四种好处:更高的产品质量、迭代时团队在分析 / 开发 / 测试等活动上可以保持更好的一致性、 更有效地实现变更、大幅降低返工。这些都意味着可以更快地推向市场,并具备更好的质量。比如说:有一个团队尽管每两个礼拜发布一次,但产品多年来都没出现严重的缺陷;有一个团队成功地改进了一个可怕的遗留系统,他们停用了缺陷跟踪系统;某个团队将产品推向市场的时间从 6 个月降到平均 4 天。重要的是这个过程并不是一件错综复杂的事情,也不是什么黑色艺术,它是完全可以达到的,只要大家付出努力,并通过正确的方式去实践,它的成功就是可以复制的。
Blogger Craig Smith 是这本书的早期评论者,他在博客中写道:
总体上来说,任何团队(尤其是敏捷团队),只要他们尝试去平衡或寻找一种适当的关于需求和测试的方法,那么他们就应该阅读这本书。针对在敏捷团队中如何处理测试和需求的问题,它很好地平衡了各种模式,提供了真实的案例学习。在我必读的图书清单中,该书位于测试类书籍的前 5 名,敏捷类的前 10 名。现在我终于明白如何正确命名内嵌在高速公路上的猫眼了!
他从书中提取了如下要点:
以下是我从书中总结的要点:
- 这是人的问题,而不是技术问题。
- 正确地构建一个产品和构建一个正确的产品是两件完全不同的事情,我们要确保他们都成功。
- 活文档,从根本上来讲,如同程序源代码一样,是关于系统功能的另一个可靠的信息源,只是更容易被获取,更容易被理解。
- 让产品待办事项更容易地管理。
- 只有当团队已经准备好实现某事项时才开始着手实例化需求,比如迭代开始的时候。
- 从目标获取范围,交流商业意图,然后团队提出解决方案。
- 冗长的描述会过度地约束系统,与其描述什么是必须要做的,不如描述为什么需要去做什么。
- 传统的验证方式有这样的问题:如果我们在业务需求和技术自动化之间转化时丢失了某些信息,那么我们就冒着引入问题的危险。
- 自动化的实例化需求,如果仍然用可被人们读懂的方式去描述,而且整个团队的成员都很容易获取到,那么它实际上就变成了并可执行的需求。
- 测试就是需求,需求就是测试。
- 将活文档视为服务不同客户和利益相关者的独立产品。
- 使用实例化需求后,可能会发现不再需要用户验收测试了。
- 改变过程时,将实例化需求作为文化变革的一部分推出,关注质量的提高,从自动化功能测试开始,引进新的工具,使用 TDD 作为阶梯。
- 改变文化,要避免敏捷术语,得到管理层的支持,实例化需求是一种更好地执行用户验收测试的方法,不要将自动化作为最终目标;不要关注于特定工具;留一个人迁移历史遗留脚本(称之为“蝙蝠侠”);跟踪谁在和谁不在运行自动化测试;聘用有经验的人;引进顾问;推行培训。
- 实行签收制和可追溯制,将需求说明放入版本控制系统中,获取活文档的签收,获取项目范围的签收而不是具体需求的签收,获取精简用例的签收,引入用例实现。
- 警告信号有:频繁改动的测试、退回返工、测试延误、以防万一的代码以及霰弹式修改(即到处修改)。
- F16 战机,原先的需求是高速,但真正的问题是要能在战斗中逃避敌人的战机,30 多年后它还是非常成功。
- 范围隐含着解决方案,制定出目标,并进行协作,确定出与目标一致的项目范围。
- 人们告诉你他们认为他们想要的,但是通过询问他们为什么想要,可以确定出新的真正的需求。
- 要了解为什么有的东西是需求的、什么人需要,是提出解决方案的关键点。
- 讨论,划分优先级和评估目标等级,可以更好地理解需求,减少所需的精力。
- 从外到内的设计模式,先从系统的输出结果开始,调查为什么需要它们,以及软件如何提供这些功能(来自 BDD)。
- 另外一个方法就是让程序员去编写故事卡的“我需要……”的部分。
- 如果你对范围没有控制权,就去询问为什么某些东西是有用的,询问另外一种解决方案,不要只关注最低那一层的需求,交付完整的功能。
- 团队协作是非常有价值的,可以尝试进行整个大团队的工作坊,也可以尝试更小的工作坊(三个人),开发人员和业务分析师结对进行测试,开发人员审核测试,使用非正式的对话进行协作。
- 业务分析人员是交付团队的一部分,而不是客户代表。
- 当你拿起一张用户故事卡,说到“我不是很确定”时,就说明详细程度十分恰当,而这会促使你与业务人员进行一次交流。
- 团队协作,进行具有引导性的会议,让利益相关者参与进来,提前准备,程序员和测试人员一起审查用户故事,只准备基本的例子,广泛地进行障碍性讨论。
- 检查需求是否完整的一个最好的办法就是设计一个与之相对应的黑盒测试用例。如果我们没有足够的信息去设计一个好的测试用例,那么我们绝对没有足够的信息去开发一个系统。
- 功能模块的例子必须具有精确性(不是简单的是或否的答案,使用具体的例子)、真实性(使用真实数据,从客户那儿获取真实的例子)、完整性(使用不同的数据组合去试验,利用其他方式去检验和测试),并易于理解(不用试验所有组合,寻找隐含的概念你)。
- 无论什么时候如果发现需求中有太多实例或实例太复杂,就要努力将其复杂度降低,描述简单化。
- 应该阐明非功能性需求,获取精确的性能需求,在用户界面设计上使用简单原型,使用 QUPER 模型(译者注:一种确定非功能性需求的方法),讨论时使用检查清单,对于那些难以量化的事项(比如要有趣味性),可以创建参考的例子用来说明。
- 好的需求说明,应该是精确的、可测试的,不应该用脚本去编写,也不应该写成流程描述的样子。
- 对系统应该如何工作的描述应予以避免,要关注于思考系统应该做什么。
- 需求说明应该与软件设计无关,不应与代码联系太紧,应避开技术难题,不要深陷在用户界面细节里。
- 需求说明应该具有自我解释性,具有描述性标题,对目标的描述要简短,能被他人理解,不要过度定义,从基本开始然后扩展。
- 需求说明要集中,使用“given—when—then”模式,不要特意细节化所有的依赖,可在技术层使用默认值,但不要依赖它们。
- 定义和使用一门统一语言。
- 从自动化开始,使用小的试验项目,事先计划好,不要推迟或者委派,避免自动化现有的手动脚本,从 UI 测试中获取信任。
- 管理自动化测试,不要将其定位成用以描述验证的二等代码。不要复制业务逻辑,根据系统边界进行自动化,不要用 UI 层去验证业务逻辑。
- 自动化用户界面,定义更高层次的交互(例如“登录功能”,而不要定义成“填写登录页面”),与 UI 需求一同验证 UI 功能,避免录制和回放,在数据库中创建上下文。
- 测试数据的管理,应避免使用预先生成的数据,使用预先制定的参考数据,从数据库获取原型。
- Bott’s Dott’s (译者注:凸起的,会反光的路面标记)是一种车道标志,在人们越线时给以警示。持续集成在软件开发中有同样的作用,在持续集成中运行实例化需求,我们就会拥有持续的验证。
- 降低不可靠性,找到最困扰的问题并将其修复,确认不稳定的测试,建立专门的验证环境,完成自动部署,对于外部系统使用测试替身(test double),实现多级验证,在事务中执行测试,对参考数据进行快速验证,等待事件而非消耗时间,将异步执行设定为可选项,不要把需求说明当成是端到端的验证。
- 为了更快地获取回馈,可以引入业务时间,将长时间测试拆分成小的模块,避免使用内存数据库做测试,区分快测试和慢测试,保持过夜测试的稳定,创建一个当前迭代包,平行地执行测试。
- 管理失败的测试,有的时候你无法修正所有的测试,这时可以创建一个回归的失败包,自动检查屏蔽的测试。
- 要让文档容易理解,应避免过长的需求说明,避免使用多个较小的需求说明去描述单一功能,寻求更高层的概念,避免技术上的自动化概念。
- 文档要一致,演进出一门统一语言,使用虚构人物,在制定语言时进行协作,记录构建单元。
- 改善文档的组织方式,便于访问,可以使用用户故事、功能区域、UI 交互路径、业务流程,使用标签而不要使用 URLs。
关于作者
Gojko Adzic 是战略软件交付顾问,他与多个具有上进心的团队合作,帮助他们改进软件产品和过程的质量。他专注于实施敏捷和精益的质量提高,尤其擅长敏捷测试、实例化需求和行为驱动开发。Gojko 经常在重要的软件开发和测试会议上发言,并运营着英国的敏捷测试用户小组。最近这11 年来,他一直在财务和能源交易平台、移动定位、电子商务、在线游戏和复杂配置管理系统等行业项目中,从事程序员、架构师、技术指导和顾问等工作。
他是如下书籍的作者:《Specification by Example》,《Bridging the Communication Gap》,《Test Driven.Net Development with FitNesse》和《The Secret Ninja Cucumber Scrolls》。
查看英文原文: Interview and Book Review: Specification by Example
感谢石永超对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论 1 条评论