实例化需求SBE

文章转自:https://github.com/larrycai/sdcamp/blob/master/contents/1-chapter5-sbe.markdown

需求管理和实例化需求

在一个产品开发中,需求是推动整个软件开发的源泉。产品经理制定需求,确定了方向,但是如果方向(需求)一开始就有问题,后面开发测试得再辛苦、再认真、再正确,对产品来说都是不合格的。

现在代码质量的检测(如覆盖率,静态代码检测等等),持续集成技术都已经积累了很多的经验,能很好得保证编码阶段代码本身的质量。需求的BUG比开发中的BUG更难发现。那有没有有效的类似的工程实践来解决需求的问题呢?

在本章,我们一起来学习需求管理中现在来看蛮有效果的一种实践--实例化需求(Specification by example)。在下章同时会通过学习相关联的Cucumber软件来切身体会怎么将需求贯穿下去。

如果实施得好,相信你的产品的总体质量会上一个台阶。

环境准备

纸和笔就可以了。

需求的困惑

如果你做过开发,就知道软件开发的最大问题之一就是需求,而且它也很容易的被作为替罪羊。在公司项目延迟和出大问题的最大借口(不过这也是事实),就是“需求不清楚”。

那把需求早点弄清楚不就行了嘛?听着挺容易,但要做好它却很困难。

需求不清楚,不能开始项目,这一点大家都有共识。一种常见的解决办法就是:高级人员要对需求文档进行审核,完全通过后才能进行项目开发。但这实际上就是瀑布模型中的思路,大家已经知道它不大行得通,时间拉长了不算,早期把所有的需求都弄清楚也会变得纸上谈兵。

那敏捷迭代起来以后是否就好点呢。理论上会好点,因为需求在一个迭代中东西会少点,有机会理清楚一点。但就是因为一个迭代的周期短,在开完计划会议后(Planning meeting),团队会更愿意直接投入到代码开发中去,他们认为需求已经可以了;项目经理也觉得讨论需求会浪费点时间,我见过得很多人包括开发者都认为写代码才是干活。

这样的话,实际上往往到一个迭代的后面几天开始测试的时候才发现:测试人员、开发人员、产品负责人想的都不是很一样,但时间不够了,要不注册BUG,要不就是挪到下个迭代。这就是**技术债务(Technical Debt)**的最大根源。

那是否有好的办法把需求质量有效得提高?

测试人员的工作文档

测试人员应该除了产品负责人对需求是最了解得,至少比开发者知道得更多^51。

再来看看现在的测试人员做了哪些事情,不同的公司可能不太一样,这里只是一种典型例子。

得到“需求”后,首先可能要写的是测试分析:考虑一下这些功能大概的测试内容和范围。它存在的主要目的是为了让其他高级测试人员来把关,确保需求理解和相应的测试没有大的偏差,其中包括时间的估计。

紧接着是测试用例的描述:比较详细得用步骤的方式来阐述每一步测试。它很有可能是测试人员进行实际测试的主要文档,为了将来其他测试人员能重复测试。

如果运气好,敏捷实施不错的话,测试人员会被要求测试自动化,然后前一步骤的测试用例会被写成测试脚本。它来替换无谓的手工测试。再进一步,它还会在持续集成的服务器中被自动执行。

最后,一般都要求写一份测试报告:完成了多少测试用例等等。这个就是经理们经常想有的一份文档,以此来作为项目实施总结报告。

上面的每一步看上去都很有必要,缺一不可。

但我建议你在旁观者角度来精益软件角度观察一下,有没有浪费^52呢:

  • 这些文档都有哪些人读呢?作用大吗?3年后还能读懂吗?
  • 可以合并一些文档吗?只有一份行不行呢?

用实例化来解决需求的问题

解决需求当然有许许多多的办法,下面是几种常见的方式:

  • 从TDD(测试驱动开发)引申出来的ATDD(Acceptance Test Driven Development: 验收测试驱动开发)。就是把TDD对开发者的成功经验挪到测试团队中,让测试人员在项目中起主导地位。
  • **BDD(Behavior Driven Development:行为驱动开发)**就是强调先搞清楚功能的业务需求,有它来指导后续的开发。
  • 实例化需求(Specification by Example):顾名思义就是要用例子的方式去阐述需求,这个概念是由Gojko Adzic提出的。

从本质上来说,实例化需求和ATDD、BDD包括其他的敏捷测试都是一个范畴,一样东西。但是实例化需求提出了更好得实践方式,减少了对工具的依赖,更容易被企业开发接受。

本章主要就是简单介绍实例化需求和实施的方法。

主要过程模式

在【实例化需求】一书^53中,Gojko提出了实例化需求的主要过程模式

主要过程模式主要包括一下几个重要环节:

  1. 从目标中获取范围:要一直牢记商业价值,为什么要做。很多时候执行项目时太关注怎么做了。
  2. 用例子来协作探讨需求:例子能更好得把需求描述清楚,不能含糊。
  3. 提炼需求说明:通过例子了解需求后就可以提炼出需要的需求说明。
  4. 执行需求说明并自动化:需求说明如果能执行并放入到持续集成后,信息就不会过期。
  5. 活文档:文档要长久,就必须要容易维护,从需求说明中自动产生出的活文档是最有效的方式。

网上书店一个例子

让我们先从一个常见的例子来学习一下,这个例子也是Gojko常用的,我可能在一些环节稍微改变了一下。

假设某个网上书店为了提高用户的回头率,就提出了口号:到年末,达到50%的用户的回头率,这就是目标(Business Goal)。一般是由CEO或最上层的市场经理根据市场决定的,他们关注的是战略方面的决策,也是整个产品开发的市场价值和背景。这一点经常被开发团队忽视,要让团队时刻知道项目的意义所在,这样在有冲突或对需求的理解产生怀疑时,就可以看看需求产生的具体原因,有时你可以想到不同的解决办法。条条道路通罗马-不过也要知道是去罗马对不对。

有了目标后,业务经理和领域专家们就可以从中提出一些要开发的项目范围(Scope),这个用头脑风暴(Brainstorming)的形式是最适当的,可能的产出点子如下:

  • 给用户打折卡
  • 通过email主动推销优惠信息
  • 买书免运费
  • 限时打折
  • ... ...

这个阶段的关键是不要扼杀好点子,要集思广益。也不需要一开始就对点子进行细化,更多的是考虑投入产出比。在讨论充分的情况下,在会议的后期可以选定觉得最好的内容再进行推敲,以此来定出需求给研发部。

这一点就是关键,因为研发部一般和市场部不在一块儿(能在一块最好),通常是通过电子化的文档接受需求,这就一定要把需求说清楚,很显然用浅显易懂的语言来表示是最好的。先别看,你自己想想如果你来写会是什么样子。

好吧,让我们继续前面的例子。

假定买书免运费这个点子不错,现在就我们就可以试试用例子的方式来阐明需求。

  • 一个普通客户买一本书,免运费。

听着不太划算,业务经理认为要有一定数量,那就先定6本吧,然后加上5本的测试例子使它更容易理解。

  • 一个普通客户买6本书,免运费。
  • 一个普通客户买5本书,运费大于0。

蛮清楚的了,再来看看还有其他情况出现吗?

一个技术人员提出了运货范围,产品经理想了想竞争对手的情况,决定只给除西藏省,青海省的大陆地区免运费,差不多大家都清楚了。

  • 一个普通客户买6本书,送货地址到上海,免运费。
  • 一个普通客户买6本书,送货地址到西藏,运费大于0
  • 一个普通客户买5本书,运费大于0。

还有吗?想了想,对了,买书的人经常顺便买个小电子产品(或化妆品,哈哈),让我们加个U盘的情况吧。

产品经理想想了,物流也不会有损失,同意。

  • 一个普通客户买6本书,送货地址到上海,免运费。
  • 一个普通客户买6本书,送货地址到西藏,运费大于0
  • 一个普通客户买5本书,运费大于0。
  • 一个普通客户买6本书和一个U盘,送货地址到上海,免运费

反应快的立马想到了冰箱。

  • 一个普通客户买6本书和一台冰箱,送货地址到上海,免运费???

要不要免呢?产品经理觉得自己做不了主,问物流经理。负责物流的业务经理连忙说吃不消了,因为大件电子商品的快递费用很高,要亏本的。行吧,那就不免吧。

  • 一个普通客户买6本书和一台冰箱,送货地址到上海,运费大于0

这条和上面的U盘有冲突,需要解决。有人立马提出按重量来判断,大家一致同意。产品经理也定下了1公斤这个分界线。

  • 一个普通客户买6本书,送货地址到上海,免运费。
  • 一个普通客户买6本书,送货地址到西藏,运费大于0
  • 一个普通客户买5本书,运费大于0。
  • 一个普通客户买6本书和一个小于1公斤的U盘,送货地址到上海,免运费
  • 一个普通客户买6本书和一台大于1公斤的冰箱,送货地址到上海,运费大于0

现在我们经过集体下定义(Specifying Collaboratively)得到了一下关键例子(Key Examples)。明显得,这种奇异是最少的,一目了然。主要原因是最自然的业务描述,人人都明白。

有了这些例子,又可以回头去审阅最原始的需求”买书免运费“,就可以提炼需求说明(Refine the Specification)来得到完整的实例化的需求说明(Specification with examples)

需求:买书免运费
   提供读者买书优惠活动,买书超过(含)6本以上的而且重量小于1公斤,可以免费送货到除西藏省,青海省的大陆地区。
关键例子:
  • 一个普通客户买6本书,送货地址到上海,免运费。
  • 一个普通客户买6本书,送货地址到西藏,运费大于0
  • 一个普通客户买5本书,运费大于0。
  • 一个普通客户买6本书和一个小于1公斤的U盘,送货地址到上海,免运费
  • 一个普通客户买6本书和一台大于1公斤的冰箱,送货地址到上海,运费大于0

看上去很完美了,写入需求文档,放入Backlog,通知开发团队在下一个Spring中实现,争取早日上线。团队成员看了看,也觉得这次需求很清晰,也没问题,就承诺在这个Spring中完成。

孰料开发团队拿到这个需求准备实施没多久,架构师发现了个大问题:现在的数据库中没有“重量”一个字段,要加入这个字段的话,这个工作量会急剧上升。

怎么办呢?这是已经承诺好的需求,反悔还来得急吗?

软件开发中(生活中或亦如此)最重要的就是任何时候有问题,自己搞不定,不能完成自己的承诺时,都需要尽早提出来,和其他人一起商讨解决方案。

产品经理了解了技术难题后,认为这只是一个小的销售方案,没必要费那么多的开发时间。为了简化起见,大家一致决定只对图书免运费。

通过沟通,双方又都满意了。更新后的需求如下:

需求:买书免运费提供读者买书优惠活动,买书超过(含)6本以上而且只含书的订单,可以免费送货到除西藏省,青海省的大陆地区。关键例子:

  • 一个普通客户买6本书,送货地址到上海,免运费。
  • 一个普通客户买6本书,送货地址到西藏,运费大于0
  • 一个普通客户买5本书,运费大于0。
  • 一个普通客户买6本书和一个U盘,送货地址到上海,运费大于0

这些是最重要的步骤,如果能实践它,已经可以得益颇多了。关于怎么去执行,那得结合工具来讲,我会在下章解释。

常见问题

在企业推动实例化需求,讲到这个例子时,经常会碰到这些问题:

6件可配吗?:例子中提到6件免运费,显然这个在系统中要可配的,不能在产品中硬编码(hard code)。但是这个需要在例子中讲清楚吗?

“否者我的开发团队又要说我需求没讲清楚,不过我总觉得这点意识他们应该有的?”,一个有着很多痛苦经历的PO问道。

没有一定的说法。在这个案例中,建议没有必要把免运费的数目可配这个要求在例子中写出来。但是如果自己的团队这方面能力不够,提醒一下,或者放在基本要求中都是可以的。记住!!最重要的是沟通,把需求澄清出,不要有歧义。

这不是Waterwall吗?:这是一个简单的例子,看上去很快就弄明白了。但是在实际中,有太多的需求要澄清呀?

”这样看上去和以前没有两样,还是要花好多时间来搞清需求,只是快了一点而已?“

不是的,在实际运作中,这是一个迭代式得不断澄清的过程,可以把最重要的先澄清。这里面还有一个很重要的是:就算在优先级最高的需求中也有不重要的小功能,这个用例子的方式很容易体现出来。

和用例有区别吗?:很多人初次接触这个时总觉得和用例没区别。

可能,但是我很少看到好的用例,用例很多时候关注在技术实现的步骤上了,所以有很多不必要的技术细节,不太适合产品经理来阅读。这儿我们要求的是一份大家都能容易读懂最少歧义的需求。

当然不排除你的用例很容易读,没有冗余,那往往就是实例化了。

如何实施

以前在估计时间时,团队很容易用含糊的原因解释。敏捷实施中又要求团队来估时间,常见的毛病就是:

我们需要1000人时(manhour),300人时是准备环境,400设计加开发,300人时是测试。

现在用实例化需求后,很容易得针对每个例子来估时间,PO也可以根据时间的代价来取舍。

认可了这种实践,实施起来也相对容易一点,下面列出几个要点(需要不断学习)。

循序渐进和现有流程的结合

我们可以不用改变现有流程的方式把实例化需求循序渐进的开展起来,这一点在企业中很重要,大的改变都很费周折。

测试分析阶段,我们可以把简单的需求列出来,加上理解的一个最重要的例子就可以了。可以结合迭代式的方式,优先级高的先多花时间来写测试用例

当然在写测试用例时,我们可以继续前面的格式,只是多加几个例子,并且持续地提炼需求说明,使得越来越清晰。

在下章中介绍如何把测试用例直接变成可测试的测试脚本

这样子,你的现有流程就不需要改变,如果你已经有现成的框架来做测试脚本,那就继续用下去吧,只要需求明白了,什么都好解决。

贴在墙上

把需求贴在墙上可视化一点也是非常有效果的,它可以减少浪费。企业最大的毛病就是会多,每个人都是认为自己的会重要,这是很浪费时间的。

完全不一定每次审阅都要去参加,只要我们把需求贴在墙上,团队就随时随地得可以了解最新的进展。随手拿个即时贴提建议:时间估计,架构的影响...

如果对某个需求需要讨论了,召集相关人(千万不要整个团队)在小房间搞清楚,然后立即更新需求。

因为我们现在用上了自然语言的实例化的需求,任何时候团队成员应该很容易读懂,而且没有偏差;如果有,说明还不清楚。

相关知识

  • 了解ATDD,BDD
  • 阅读从用户体验中挖掘需求一种方式"体验设计7日谈之一:关于软件的体验设计":http://www.infoq.com/cn/articles/xzc-experience-design-software
  • 了解特性注入(Feature Injection): http://www.infoq.com/cn/news/2009/05/feature-injection-comics

课后练习

  • 试着把身边最近工作过的一个需求用这种方式体会一下。

小结

实例化需求是一种很棒的协作探索需求的好办法,它强调了无时不刻地沟通的必要性,还有就是用例子来讲述需求更容易理解。但是要用熟练了还是很有难度得。

参考阅读

  1. Book: Specification by example. http://manning.com/adzic
  2. Specification by example: http://specificationbyexample.com
  3. 精益软件开发: http://zh.wikipedia.org/zh/%E7%B2%BE%E7%9B%8A%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
  4. 实例化需求中文书:http://www.ituring.com.cn/book/837

你可能感兴趣的:(项目管理)