# 需求的细化
# 结构化故事
scrum没有规定把用户需求转化为PBI时应该用什么样的格式,但是大部分人还是更推荐:"作为一个...我想...我就可以..."这种形式来完成用户故事.
# 分解
除了典型可以直接用于Sprint的用户故事,还有两种常用语描述需求的构建:篇章故事(epic)和任务(task).
epic需要超过一两个sprint进行开发和测试的用户故事,刚开始定制产品列表时,大多数需求自然更接近epic.在scrum中需求是逐步涌现出来的,没有必要再已开始就把所有需求分解为详细的用户故事,只需要保证产品列表里有足够做一两个sprint的条目是详细的用户故事.
# 任务切片和切割
SBI(Sprint Backlog Item)制定出可操作且适合在一个sprint内完成的用户故事对于我们来说是一个挑战,接下来在sprint planning上把优先级最高的故事变为sprint列表.
通常sprint列表不仅包括这些用户故事,还包括他们的衍生物,也通常称称为任务(task).这些具体而详细的故事是开发团队成员在整个sprint中的工作对象.通常在任务看板中上用各种颜色的便利贴来跟踪,任务大小一般在2~8小时之间.超过8小时的任务可能会缺乏灵活性.
把epic切成用户故事是一件需要思考的事情,我们拿一个常见的划分方式来举例,面对登录我如果不经思考可能会向下面这样来划分: "作为一个新的用户,我希望登录到xxx网站,这与我就可以享受他的专属服务了"
- 任务1: 设计端到端功能测试用例
- 任务2: 生成测试数据
- 任务3: 开发数据库层
- 任务4: 开发业务逻辑层
- 任务5: 开发用户交互层
- 任务6: 开发端到端功能型自动测试案例
- ...
这种拆分看起来符合逻辑,而且简单易懂,但是它的本质确实一个迷你型的瀑布开发,仔细看一下任务,产品负责人会发现所有的任务全部完成之后他在有机会验证需求是否得到满足.从用户功能方面来说,让产品负责人检查数据库架构的变化以及相关的数据逻辑不一定可以保证开发的方向正确.
我们换一个角度,为什么不在任务层面上也使用广泛应用于故事层面的纵向切片法呢,我们试着这样做一下: "作为一个新的用户,我希望登录到xxx网站,这与我就可以享受他的专属服务了"
- 任务1: 开发用户名/密码功能(包括测试设计和自动化)
- 任务2: 开发第三方鉴权功能(包括测试设计和自动化)
- 任务3: 开发登录页面功能(包括测试设计和自动化)
- ...
这里,我们把故事分成了一些封装好了的用户功能,每一个包括一个小块数据库工作,业务逻辑和用户界面实现.这里的时候会让很多人产生了一个疑惑,如果把这个故事切成更小的功能,为什么不把这些功能叫做单独的故事而当做任务呢.首先"故事要对用户有价值",对于用户来说登录网站肯定有价值,但是一个单独的第三方鉴权功能并不一定会有价值.另外故事需要独立性,如果能把故事分的更小而且还能独立给他们排列优先级,那么把它们作为单独的故事而不是任务就是有道理的,看一下我们这个案例,没有一个任务能够排列优先级,因为从客户的角度来说,价值不完整也不连贯.
# 技术故事和软件错误
技术故事常常是我们不感兴趣但又不得不做的事,比如升级数据库,清除没用的代码,重构混乱的设计或实现一个老功能的测试自动化.
谈论技术故事时,常常听到下面两个问题:
- 既然用户故事是以用户为中心的,技术故事又应该怎么写呢?
- 我们怎么用用户故事的常用格式来写技术故事呢?
针对第一个问题,理想的回答可能是:"不到万不得已,就不要写独立的技术故事,最好尝试在某个和这个技术相关的功能型用户故事中把它作为一个技术需求以任务的形式表达出来",如果有多个功能型用户故事都依赖于这个技术工作,则可以在优先级最高的用户故事中体现.
把技术工作放在功能性故事中,主要是想确保产品负责人不会因为客户对技术不感兴趣而忽视它,在功能性故事中体现技术,技术工作肯定不会被漏掉,而且产品负责人还会开始理解故事本身的技术复杂性.
关于第二个问题,我咨询过一些资深的scrum教练,他们的答案是没必要一定这么做,有些人喜欢用用户故事格式来写功能性故事,但这个格式不一定适用于技术故事.相反,可以选用合理而且便于理解的沟通格式,用一种生硬的方式来表达会不自然而且容易让读者困惑.
# 制定完成标准
我的团队最近经历了一些糟糕的项目体验,我的开发同事完成了一项scrum任务后很自豪的和我说:"看,你说的功能我都完成了",但是我看到的时候突然发现,虽然开发的同事很努力,但这个任务并不能满足我的完成标准,整个功能实现的太简陋了,不足以提供给用户使用.当你有两个或更多人参与同一个事务的时候,最重要的是设定一个统一期望值,scrum理解这句格言的重要性并提供了一个重要的概念来帮助我们做到这点: 完成标准(Definition of Done)
# 不清晰的争论
我们在工作时,大家经常针对一个时期饶了很大的弯,不停的兜兜转转的浪费时间,最终也没有结论,最后各方都很沮丧的不欢而散.在我以往的工作经历中,开发和测试在讨论质量时发生这样的矛盾数不胜数.程序员坚持自己的代码以及满足需要,而测试说事实上恰恰相反.谁是对的呢,这个事情并没有对错之分,问题在于构成足够质量标准的规则没有清楚的定义或者没有进行良好的沟通.
DoD是共同开发制定的,就能极大避免这些争吵的发生.DoD成为一个指导开发工作的协议,清楚列出一项任务需要完成哪些工作后才能归为"完成".
# DoD从哪开始
在制定第一个DoD时,首先要意识到它不是一成不变的,它是会不停演进的.DoD也需要定期检查和修正,团队通过改进其工作实践来拓展标准DoD,这可以使团队持续改进他们的效率.
在最初制定DoD,建议一定要现实甚至保守,它的定义要根据产品的具体需求以及团队的能力和期望来定制.还有要确保整个scrum团队,包括开发人员,产品负责人和ScrumMaster都参与制定和改进DoD.
# 多层次的DoD
DoD适用于多个不同的层面.任务,用户故事和交付都可以有其对应的DoD.
任务层面(以编程任务为例)
- 代码经过单元测试
- 代码经过codereview,确保代码符合编程标准
- 代码被提交到源码库,而且有清楚的递交说明以保证可追溯
- 递交的代码没有破坏构建
- 任务看板被更新,剩余的时间为0
用户故事层面
就绪标准:
- 用户故事已经被估算过
- 有一组清楚定义的验收标准
- 用户故事在产品列表中优先级已经确定
- 有适当且适用的扩展文档
- 基于初始计算,这个用户故事可以轻松放入一个sprint
完成标准:
- 所有自动化功能验收测试正式新功能可以如期端到端的工作
- 所有回归测试正式新功能和其他功能的成功集成
- 所有相关的构建/部署脚本都已经修改并且测试过
- 最终的运行功能已经由产品负责人全部检查和接收
- 所有的最终用户文档都已经写好并且检查过
- 开发团队已通过sprint planning 想所有相关干系人演示用户故事
交付标准:
- 和这个交付相关的代码都已经成功的部署到产品服务器上
- 交付通过所有产品级的冒烟测试,采用的是实际的产品数据,而不仅限于测试数据
- 市场和运营团队都已经接受了新特性培训
- 产品负责人已经检查和接收最终的交付
# 限制因素
除了前面所述的例子,DoD还经常反映了一些需要符合规定的系统限制因素,典型的限制包括可伸缩性,可移植性,可维护性,安全性,可扩展性以及交互操作性等等.这些需求需要融入产品的所有层面,从任务级别一直到交付级别:
- 可伸缩性: 规模必须能扩充到同时支持xxxx万用户
- 可移植性: 任何使用的第三方技术都需要是跨平台的
- 可维护性: 所有模块都需要保持清楚的模块化设计
- 安全性: 必须通过具体的安全渗透测试
- 可扩展性: 必须确保数据接入层可以和所有商用关系型数据库相连
- 交互操作性: 必须能够实现套件中所有产品的数据同步
# 接收标准还是完成标准?
逐步熟悉DoD和用户故事的格式后,就可以时不时碰到一个有趣的问题:一个需求应该是接收标准的一部分还是完成标准的一部分呢?这个问题的答案去决议这个需求是适用于所有用户故事,还是用户故事里的一个子集.以向后兼容的例子来说,这个非功能型需求就应该是DoD的一部分.另一方面,如果确定只有几个特定的开发功能需要向后兼容,那么这个需求就应该放入这些功能相关的接收标准.
# 渐进启示
"scrum不是万能的银弹,它是一面银镜",这句话说明scrum并不是能帮你解决项目灾难的万能银弹,但它能帮你今早发现哪些地方需要改进.瀑布式流程只有到最后才能让你仔细观察产品或流程,通过scrum,团队会频繁的照镜子,好让团队防患于未然.
# 检查和验证
演示的目的是和团队再次确认他们承担的工作在交付时与所有人的期望一样,开发人员如果想和产品负责人确认他没有误解他为什么要做哪些PBI,可以要求演示.或者产品负责人如果想在投资大量的时间和经理之前检查一下设计决定,也可以要求演示.
由于scrum强调提高面对面的交流和频率,所以我们常常会发现有更多不同意见.越定期的互动,越容易平息争论并使所有人重新回到正确的方向.
只要需要,人和人都可以演示.我们可以固定时间安排一些时间段来看一下演示的结果.至于哪些人需要参加演示,建议始终要同时包括产品负责人,相关的开发人员以及测试人员.因为我们希望更多依赖与讨论而不是规范,所以保证所有人都有相同的理解并保持意见一致相当重要.
# 问题和调整
演示应该完全专注于当前sprint列表的内容,而不是讨论未来的故事.演示有效的输出通常有以下几类:
- 问题: 开发中发现的问题体现在不正常而且需要修复的功能上
- 调整: 设计微调,不要把范围蔓延带入整个用户故事中
- 鼓励: 如果演示证实开发出来的产品与需求一致,需要得到正向的反馈来鼓励整个团队
# 范围蔓延
如果产品负责人在演示中决定调整一下用户故事的需求该怎么办呢? 这个场景非常普遍而且令人沮丧,我们可以额外创建一个用户故事来关注新的问题,并且把它放到产品列表,如果这个用户故事的优先级很高,就要放到下一个sprint planning进行讨论,这样就自然而然的放到下一个sprint处理,而不是改变这个范围.团队在一个sprint中需要有节奏的专注,所以为了确保项目安全,我们要尽力控制范围蔓延.