用“实例化需求”,让需求澄清更高效(下)

简介: 用“实例化需求”,让需求澄清更高效(下)

04 用自动化测试来频繁验证需求

image.png

  • Tip1:测试是为了验证需求,因此不可以只偏重于测试本身,而忽略了测试和需求之间的联系。过度饱和的数据和测试用例的大爆炸是不可取的。
  • Tip2:还是那句,测试是为了验证需求,因此不要在测试代码中引入业务流程或者业务逻辑,不要验证系统是怎么做的,而要验证系统做的事对不对。
  • Tip3:自动化测试有很多种优秀的工具,但不要执着于于特定工具,认为工具才是解决问题的王道。工具是为了测试服务的。

在传统的流程中,庞大的需求说明往往跟不上实际开发中的需求变更,导致需求文档在交付之时就已经过时。代码才是唯一能真正信任的。但是,如果通过持续集成对需求说明进行频繁验证,我们就能及时发现需求说明和系统代码之间的差异,及时解决它们,从而保证需求说明和代码是一直同步的。可以像信任代码一样信任需求说明。

频繁验证的依据就是提炼需求产生的实例化需求,它是所有过程实施中都必须要反复进行的工作。需求通过频繁验证与用户进行频繁确认;设计通过实例 化需求来频繁验证设计是否满足用户的需求;开发通过实例化需求频繁验证代码中业务逻辑;测试通过实例化需求来频繁验证交付的功能,并作为最后验收测试的依据。

提炼好功能的需求说明之后,我们就有了实现要达到的清晰目标,并且有了一个精确的方式来衡量何时已经实现了目标。每当系统有所变更,提炼过的需求说明就可以用来检查原有功能是否依然生效。自动化验证带实例的需求说明中,如果必须大量修改需求说明,那么就会失去提炼需求说明带来的价值。

主流自动化可执行需求说明工具中,自动化代码依赖于需求说明,而需求说明并不依赖于自动化代码。

手动测试中,准备上下文环境所花的时间往往是主要瓶颈所在。而在自动化测试中,时间主要花在了寻找测试失败的原因上。传统的自动化测试描述的是一系列相互依赖的步骤,所以出了问题很难定位究竟是什么导致了问题。因此如果我们不去使用一个较大的脚本,转而使用更多较小的、专注的且独立的测试,那么可以让测试更具弹性且可以降低维护成本,可以更快找出问题。

用户界面自动化的3个层次:

  1. 业务规则层。测试所展示的或所操作的是什么?例如:为购买2本或2本以上书籍的客户提供免费送货服务。
  2. 用户工作流层。用户如何通过UI使用某个功能,以更高的行为级别应该怎么描述?例如,将2两本书放进购物车,输入地址信息,然后验证配送选项是否包含免费送货服务。
  3. 技术行为层。操作单个工作流的步骤需要哪些技术性步骤?例如:打开店铺主页,使用testuser与testpassword登陆,跳转到/book页面,点击CSS类是book的第一个图片,等待页面加载结束,点击购买链接等。

需求说明应该以业务规则层来描述。自动化层应该通过组合技术行为上编写的程序块来处理用户工作流层。这样的测试易于理解、编写高校,而且维护成本也相对较低。

1. 活文档系统

维护需求文档,通常是件让人头疼的事情。过于繁琐的需求文档会让人丧失维护的动力。可是,系统的重构和更新又偏偏需要这样一份文档。怎么办呢?所幸的是,实例化需求为我们提供了这样一种省时省力的方式——从自动化测试用例中提取文档!

最成功的团队不会满足于一些频繁验证的可执行的需求说明,他们能确保很好的组织需求说明,让大家很容易找到和获取,并让他们保持一致。活文档是关于系统功能可靠的、权威的信息源。他和代码一样可靠,但是更容易阅读和理解。支持人员可以用它来查明系统在做什么以及这样做的原因。开发可以用它作为开发目标。测试用来测试。分析功能变更请求的影响时,业务分析师可以从他开始着手。还提供了回归测试。

提炼出来的需求实例是对系统做了什么事最有力、最准确、最新鲜的描述。而自动化测试用例又使用了可执行的方式实现了这些需求实例,我们再使用一些工具把自动化测试用例提炼为HTML或是PDF的文本,那么,砰!一份简单易懂的活文档就产生了!水到渠成,简单易懂,永不过时!

如果没有活文档,任何重大的重构都是自寻死路。

  • Tip1:活文档和敏捷中的用户故事卡有什么区别吗?好像很类似的样子。当然有所不同。用户故事是用故事的形式描述需求,活文档则是运用实例。另一个不同是,敏捷的故事卡在Sprint结束之后就没有用了,通常不会长久保存,而活文档则是易于保存,同步更新的。
  • Tips2:活文档必须组织的井井有条,便于访问。
  • Tips3:用户故事作为计划的工具是非常出色的,但是他在组织现有系统功能方面没有太大用处。因此可以以功能区域组织活文档层次结构。当前迭代的需求说明是以用户故事和功能来组织的。

image.png

05 操作流程

1. Pre-planning Meeting

参加人

产品、开发、测试代表

目标

选择优先级高的需求进行需求澄清和实例撰写、精炼,获得相对成熟的需求规格说明书,并明确下一迭代的backlog。

内容

产品准备好需求说明和基础实例(描述预期功能的关键实例,作为测试的基础用例),产品、开发、测试代表一起对需求进行澄清。

随后开发和测试一起对实例进行扩展(如边界情况、需重点标识的有问题的地方),再精炼,得到相对成熟的需求规格说明书,并准备好cucumber的验收标准。

基本要求是将下一个迭代的全部需求的需求说明和基础实例准备好,其中优先级高的有若干个可以已准备好cucumber验收标准。

小技巧

反馈调查。是检验一组人员是否对需求说明达成共识的好方法。在讨论过一个故事之后,如果有人对故事提出了一个特殊用例,工作坊的主持人必须请参与者写下他们认为系统应该怎样工作,然后比较全组的回答。如果回答不一致,可以按回答结果分成多个小组,每个小组选出一个人来解释他们的回答。通过讨论可以揭示误解的根源。

“我们能出找出会让这个例子失效的数据?”

备注

  • Pre-planning meeting不一定要和迭代绑定,只要能保证每次迭代的需求都已经满足上述基本要求即可。
  • 在敏捷开发中,用户故事的拆分是一个难点,因为既要保证故事足够小,又要在一个迭代中做到端到端。对于用户故事来说,除了 Card, 还有更重要的 Conversation 和 Confirmation 。如果用户故事的“撰写”、“拆分”都是由团队中的个人完成的,那么无论是不是采取了故事卡片的形式,无论是否进行了拆分,它其实和传统的需求分析方法没有什么区别。真正有别于传统需求方法的,是我们可以通过一组有序的工作步骤、通过协作,从看似模糊、混乱的业务需求中梳理出清晰的脉络,把它们从需求的重重迷雾中发掘出来,识别、澄清、归类这些细节,然后按照价值大小、成本高低、依赖关系等因素为它们分配优先级,成为可以在开发迭代中持续流动的价值单元,以此指导后续的开发活动。因此实例化需求其实是给出了一个需求澄清活动的更好方式。我们并没有去“拆分”用户故事。我们在“讨论”用户故事。讨论使得用户故事的工作流、业务规则都已经足够详尽。事实上,现在不是用户故事拆不开的问题,而是要多细节,就有多细节,也许我们发现,为了方便管理,有些场景下还可能需要做一些小的归并。无论如何,迭代项怎么划分的自主权已经完全把握在工程人员手中。例如,我们可以选择首先实现一个工作流的主干部分,可以选择首先实现工作流的一个业务步骤,可以选择首先实现几条业务规则,推迟后续几条业务规则,等等。因此实例化需求的输出并非和用户故事一一对应,而是可以先对产品功能进行讨论,形成清晰的认知后,再基于多种因素来安排迭代开发中的用户故事。
  • 并不是需求的所有情况都讨论完毕,才能开始迭代,需求只要有了一个完整的例子就能开始迭代。尚未讨论完全的情况可以视作模糊的东西在迭代中做探索。即便是简单的例子,在程序开始开发后也能发现问题。通过完成一些例子反而能够更好辅助后面未讨论完全的场景明晰起来。在项目开始阶段实例化需求工作坊会比较密集,但是这样的讨论每个迭代都应该持续发生,用户故事卡片,是一种占位符(Card),能够持续推动活动进行。

2. Scrum Planning Meeting

参加人

团队全员

内容

产品对本次迭代需求进行讲解和澄清。

产品、开发、测试一起对backlog里故事的需求说明及实例进行审核。

随后开发进行规模评估和任务拆解。

需要指定故事负责人。故事会分配给某个特定的开发,他会坚持到该故事完成,他负责与其他团队进行沟通、有效传递信息而无需所有开发人员都参与审核来确保他们理解故事,在看板上跟踪进度、在每日例会上检查状态和清除障碍)开会并仔细检查所有测试。

3. Scrum过程中

待澄清

针对还未形成cucumber验收标准的需求,开发与测试结对,扩展和精炼实例,并编写cucumber验收标准。

在完成编写后,与产品再次进行确认,三方沟通无误后,该需求可进入待实现队列。

待实现

针对已经相对成熟的需求,开发编写BDD测试代码(TDD也进行),然后进行实现。过程中有发现新的用例,则对需求规格说明和cucumber进行更新。

在开发阶段结束前,所有可执行的需求说明都必须运行通过,且通过开发自测。

待验证

测试对已经通过自动化测试的故事进行手工测试和探索性测试。

待验收

全部测试通过后,团队给产品做一个快速的产品演示,让他验收。

待部署

全部集成后,重新运行整个系统的自动化测试,测试对核心功能做手工测试,无误后,代码可上线进入生产环境。

目录
相关文章
|
2月前
|
Java
嵌套类大揭秘:代码高效组织的必备技巧
嵌套类大揭秘:代码高效组织的必备技巧
9 1
|
2月前
|
设计模式 算法
|
11月前
|
设计模式 JSON 数据格式
【工作中问题解决实践 六】基于反射及类装饰模式的数据对比框架(上)
【工作中问题解决实践 六】基于反射及类装饰模式的数据对比框架(上)
89 0
|
11月前
|
JSON 数据库 数据格式
【工作中问题解决实践 六】基于反射及类装饰模式的数据对比框架(下)
【工作中问题解决实践 六】基于反射及类装饰模式的数据对比框架(下)
82 0
|
12月前
|
存储 Java 程序员
JVM - 写了这么多年代码,你还不知道new对象背后的逻辑?
JVM - 写了这么多年代码,你还不知道new对象背后的逻辑?
105 0
|
12月前
|
存储 安全 Java
基础一:一切都是对象
基础一:一切都是对象
71 0
|
测试技术 领域建模 数据安全/隐私保护
用“实例化需求”,让需求澄清更高效(上)
用“实例化需求”,让需求澄清更高效(上)
472 0
用“实例化需求”,让需求澄清更高效(上)
|
设计模式 Java
教你借助设计模式限制实例化数量 | 带你学《Java面向对象编程》之七十三
开发过程中,如果遇到了某些要求,需要限制实例化类的数量时,需要借助本节介绍到的单例与多例设计模式来实现。
教你借助设计模式限制实例化数量   | 带你学《Java面向对象编程》之七十三
|
Java C++
保守VS开放?看清封装对象属性 | 带你学《Java面向对象编程》之四
高楼万丈,起于平地。本节通过对比正反几个实例剖析了封装对象属性的必要性,介绍了进行封装的基本原则。
保守VS开放?看清封装对象属性   |  带你学《Java面向对象编程》之四