第I部分 起步
第1章 概览
- 软件需求是一个沟通问题。一旦任何一方再沟通中把持绝对地位,项目就会遭受损失。如果业务方把持绝对地位,他们就会关注软件功能和交付日期,却很少关注开发人员是否能够同时满足这两个目标,或者开发人员是否确切地了解需求。如果开发人员把持绝对地位,技术术语就会代替业务语言,从而导致开发人员无法倾听业务方的实际需求。P3
- 用户故事描述了对用户、系统或软件购买者有价值的功能。用户故事由以下三方面组成。P4
- 一份书面的故事描述,用来做计划和作为提示,卡片(Card)。
- 有关故事的对话,用于具体化故事细节,对话(Conversation)。
- 测试,用于表达和编档故事细节且可用于确定故事何时完成,确认(Confirmation)。
- 卡片代表客户用户故事而不是记录需求。用户故事代表对用户有价值的功能。P4
- 如果一个故事很大,我们有时候就称之为史诗故事(Epic)。史诗故事可以分成两个或更多的小故事。P5
- 我们并不需要不断地分解故事,直到有一个故事能够覆盖每一个细节。类似的,用户故事不需要像典型的需求文档样式那样扩充。与其写下这些故事细节,还不如让开团队和客户讨论这些细节,即在这些细节变得重要时才讨论。P5
- 故事并不是具有契约性质,达成的协议将由测试来记录,这些测试将演示故事是否被正确开发。P5
- 用户的期望最好以验收测试的形式被记录下来。开发人员如果能了解客户的期望,他们便能指导什么时候算是完成了客户要求的功能。P6
- 客户为什么要编写故事?
由客户团队而不是开发人员来编写用户故事基于两个原因。首先,每个故事必须用商业语言来写,不是用技术术语,这样一来,客户团队可以排列故事的优先级,放入迭代和发布。其次,作为主要产品构想着,客户团队所处的位置最适合描述产品行为。P6 - 一个项目的用户故事初稿通常是在故事编写工作坊(workshop)中写就的,但用户故事可以在项目生命周期的任何时候编写。在故事编写会上,大家集思广益,充分想象用户故事。有了可以开始工作的故事集合后,开发人员便可以估计每个故事的大小。P8
- 客户团队和开发人员一起选择迭代长度,可能一周到四周的时间。在项目进行期间将使用同样的迭代长度。在每轮迭代结束时,开发人员将负责发布完全可用的应用程序子集。客户团队在迭代期间高度参与,与开发人员谈论迭代期间正在开发的故事。在迭代期间,客户团队也会详细定义测试,并且跟开发人员一起编写运行自动化测试。此外,客户团队要确保项目能够达成交付所需产品的目标。P8
- 一旦确定迭代长度,开发人员就会估计每轮迭代中可以做多少事情。我们称之为速率(velocity)。团队的第一速率估计可能是错误的,因为无法事先知道团队的速率。然后,我们可以用初步估算来勾勒出大致的蓝图或者发布计划,用以说明在每轮迭代中会完成哪些工作,需要多少轮迭代周期。P8
- 为了做发布计划,我们把故事排列成许多堆,每一堆代表一轮迭代。每一堆包含一定数量的故事,其中故事的估算中和不超过事先估算的速率。最高优先级的故事放在第一堆。当那一个堆放满以后,次高优先级的故事放入第二堆(代表第二轮迭代)。这样持续进行,直到已经有很多堆故事需要完成,估计会占用完这个项目的时间为止,或者直到这些故事堆已经可以代表产品的一个新发布计划为止。P8
- 在每轮迭代开始前,客户团队可以在中途修正计划。当迭代结束后,我们可以得知开发团队的实际速率,然后用它代替估算速率进行估算。这意味着每一堆故事可能需要通过增加或者移除来进行调整。有些故事可能比预期的简单很多,所以有时开发团队想在迭代中完成另外的故事。但有些故事比预期的难,这时就要把有些工作移到下一轮迭代或者下一个发布计划中去完成。P9
- 一个发布由一个或多伦迭代组成。发布规划指的是确定项目时间表和预期功能集合之间达到平衡。迭代规划涉及选择迭代包含的故事。客户团队和开发人员在发布和迭代规划中都要参与。P9
- 客户团队首先从排列故事优先级开始。在排列优先级时,他们要考虑下面几点。P9
- 大部分用户和客户对特定特性的渴望程度。
- 小部分重要用户和客户对特定特性的渴望程度。
- 故事之间的关系。例如,“缩小(zoom out)”这个故事的优先级可能不高,但是它可能被看作是高优先级的,因为它与高优先级的另一个故事“放大(zoom in)”互补。
- 在许多故事的优先级上,开发人员可能与客户团队意见相左。他们可能基于技术风险方面的考虑,或者由于某个故事是其他故事的互补故事,而建议改变故事的优先级。客户团队应该倾听他们的观点,但是随后排列故事优先级时,应该坚持客户组织利益最大化的原则。P9
- 为发布中的所有迭代分配故事后,发布计划便“浮出水面”。要确保每轮迭代中分配的故事点数不超过开发团队预期的速率。P10
- 为什么编写用户故事而不继续编写需求文档或者用例(use case)?P12
- 用户故事强调对话交流而不是书面沟通。
- 用户故事可以同时被你和开发人员理解。
- 用户故事的大小适合于做计划。
- 用户故事适用于迭代开发。
- 用户故事鼓励推迟考虑细节,直到你非常清楚地了解自己的真正需求。
- 由于用户故事没有技术术语(记住,它们是由客户团队编写的),所以开发人员和客户团队双方都能理解。P12
- 总结。P13
- 故事卡包含对用户或者客户有价值的功能的简短描述。
- 故事卡是故事的可见部分,但客户团队和开发人员关于故事的对话更重要。
- 客户团队包括哪些确保软件符合潜在用户需求的人,可以包括测试人员、产品经理、实际用户和交互设计师。
- 故事卡由客户团队编写,因为他们最了解如何表达需要实现的需求,也因为他们会在后期与开发人员共同确定故事细节并安排故事的优先级顺序。
- 按照故事对客户的价值来安排故事的优先级顺序。
- 将各个故事放入迭代,进行发布与迭代规划。
- 速率是开发人员可以在一轮迭代中完成的工作量。
- 放入一轮迭代的故事估计总和不能超过事先开发人员预计的速率。
- 如果故事太大以至于无法在一轮迭代中完成,可以考虑把它分成两个或更多的小故事。
- 验收测试用于验证实现的故事是否开发成符合客户团队的设想。
- 用户故事是很有意义的,因为他们强调口头交流,你和开发人员都可以理解,可以用于进行迭代计划,在迭代开发过程中能很好地工作,而且因为他们鼓励推迟细节。
第2章 编写故事
- 一个优秀的故事应该具备以下特点(INVEST):P15
- 独立的(Independent)
- 可讨论的(Negotiable)
- 对用户或客户有价值的(Valuable to Purchasers or Users)
- 可估计的(Estimable)
- 小的(Small)
- 可测试的(Testable)
- 独立的:我们要尽量避免故事间的相互依赖。出现这种依赖时,有两种方法可以绕过这种依赖。P15
- 将相互依赖的故事合并成一个大的、独立的故事。
- 用一个不同的方式去分割故事。
- 可讨论的:故事是可以讨论的。若我们把故事卡用于提醒开人员和客户进行关于需求的讨论,那么故事卡包含下面的信息就变得有意义。P16
- 一两句短语,用来提醒开发人员和客户进行对话。
- 一些注释,用以表明在对话中亟待解决的问题。
- 对用户或客户有价值的:“每个故事必须对用户有价值”,这话说起来很诱人,但那是不对的。应当避免那些只对开发人员有价值的故事。P18
- 可估算的:对开发人员来说,能估算故事的大小(至少猜一下),或者是把故事变为可用代码的时间量是很重要的。一般有一下3个原因会导致故事不可估计。P18
- 开发人员缺少领域知识。
- 开发人员缺少技术知识。
- 故事太大了。
- 当无法估算某个任务时,可以让一个或多个开发人员去实施极限编程(XP)中所谓的探针实验(spike)。开发人员不需要做十分深入的研究,只要能够答题了解足够信息来估算这个任务即可。探针试验本身总是会限定一个最大时间量(称为时间箱,timebox),用这个时间量作为探针试验的估算。如此,一个不可估算的故事就变成了两个故事:一个快速探针故事(用来获取足够的信息)和一个故事(真正实现功能)。P19
- 如果希望暂时不细化系统的一部分功能,可以考虑写一两个史诗故事(epic)。也可以给史诗故事一个大的比较虚的估算值。P20
- 小的:故事的大小很关键,故事太大或太小,都无助于制订计划。使用史诗故事来开展工作会很困难,因为它们通常包含多个故事。史诗故事需要分成更小的故事。合适的故事大小最终取决于团队、它的容量及使用的技术。P20
- 史诗故事通常分为以下两种。P21
- 复合故事(compound story):复杂故事是由多个小的故事组成的史诗故事。
- 复杂故事(complex story):复杂故事是其本身就很大且不容易分解的故事,可以将它分成连个故事:一个做调研的故事和一个开发故事。
- 考虑将探针试验放在不同的跌代里。P22
如果可能,一种较好的做法是把做调研的故事放在一轮迭代中,另外的故事放在接下来的一轮或几轮迭代中。 - 合并故事。P23
故事太小,在极限编程的团队中,一个比较好的方法通常是将其合并到需要半天活几天完成的故事中。 - 可测试的:故事必须是可测试的。成功通过测试可以证明开发人员正确地实现了故事。P23
- 小结。P24
- 理想情况下,故事之间是独立的。有时很难做到这一点,但我们要尽量实现这一目标。故事之间的交付顺序应该是无关的,可以任意拿一个故事来实现。
- 故事细节由用户和开发人员讨论得出。
- 故事应该很清晰地体现对用户和客户的价值。最好的做法是让客户编写故事。
- 故事可以注释一些细节,但是过多的细节会使故事难以理解,也可能给人一种开发人员和客户无需交谈的错觉。
- 给故事加上注释的最好方法是给它编写测试用例。
- 如果故事太大,复合故事和复杂故事可以分成几个小的故事。
- 如果故事太小,几个小故事可以合并成一个较大的故事。
- 故事应该是可以测试的。
第3章 用户角色建模
- 在编写故事前识别用户角色、角色建模、角色映射和虚构人物有很多好处。P27
- 把这些单独的客户进行分组,把每一类作为一种“用户角色(User Role)”。用户角色是一组属性的集合,这些属性刻画了一群人的特征以及这群人与系统可能的交互。P28
- 我们将使用一下步骤来识别、选择有用的用户角色集合。P28
- 通过头脑风暴,列出初始的用户角色集合。
- 整理最初的角色集合。
- 整合角色。
- 提炼角色。
- 别了识别用户角色,客户和开发人员(多多益善)聚集在一个房间里,房间里要有一张大桌子或一堵墙,这样他们就有地方粘贴或者固定卡片。理想情况是在项目启动时,把团队所有成员聚集在一起进行用户角色建模。P29
- 一个用户角色是一个用户:对项目的角色进行头脑风暴时,要坚持“已确认的角色代表的是单一用户”的原则。P29
- 整理最初的角色集合。P30
接下来需要整理这些角色。在桌子上或墙上移动卡片的位置,以表明角色之间的关系。对于有重叠的角色,把它们相应的卡片也重叠在一起。如果角色只有一点点重叠,那么卡片也只重叠一点点。如果角色完全重叠,那么卡片也完全重叠。P31 - 系统角色。P31
尽量坚持一个原则:用户角色定义的是人,而不是其他外部系统。如果觉得有帮助,可以偶尔确认一个非人物的系统角色(non-human user role)。然而,确认用户角色的目的是确保我们很周到地为用户考虑,我们要绝对地、积极地让用户对新系统感到满意。我们不需要为每一个可以想象得到的系统用户建立角色,但需要那些能影响项目成败的角色。由于其他外部系统很少会是我们系统的购买者,它们很少能决定我们系统的成败。自然,事情总有例外,若觉得加入一个非人物的系统角色有助于思考系统,将它加入也未尝不可。 - 整合角色。P32
在角色分组完成后,试着整合及浓缩角色。可以从完成重叠的卡片入手。首先,这些卡片的作者描述一下他们的角色究竟代表什么,在简短的小组讨论之后,再判断这些角色是否等同。如果等同,那么这些角色要么合并成一个单一的角色(也许可以根据这两个初级的角色名取一个新的名字),要么丢掉其中一张角色卡。 - 提炼角色。P32
给每个角色定义一些特征来建立角色的模型。角色特征是关于同属于这一类的用户的事实或有用的信息。任何可以区分这个角色的信息都可以用来做该角色的特征。这里有一些适用于任何角色建模的角色特征。- 用户使用软件的频率。
- 用户在相关领域的知识水平。
- 用户使用计算机和软件的总体水平。
- 用户对当前正在开发的软件的熟悉程度。
- 用户使用该软件的总体目标。有些用户注重使用的便携性,有些关注丰富的用户体验,等等。
- 虚构人物。P33
识别用户角色是一个伟大的飞跃,但对于有些更为重要的用户角色,再进一步为角色创建一个虚构人物是很值得的。虚构人物是假想的用户角色代表。要注意,应该事先做好充分的市场和目标用户群调查,要确保虚构人物能够真正代表产品的目标用户。 - 极端人物。P34
考虑极端人物很可能会让你编写出原本可能遗漏的故事。 - 小结。P35
- 大部分项目小组只考虑单一的用户类型。这会导致软件忽略原本需要的一些用户类型。
- 为了避免从单一用户的角度编写所有故事,要识别与软件交互的不同用户角色。
- 通过对每个用户角色定义相关特征,可以更清楚地看到不同角色的不同点。
- 对于有些用户角色而言,用代表人物来描述会很有帮助。虚构人物是假想出来的用户角色代表。他们有名字,有照片,还有足够的相关细节,因为对项目成员来说,很真实。
- 对于有些应用程序,极端人物可能有助于搜集原本被遗漏的故事。
- 开发人员职责。P35
- 负责参与确认用户角色和虚构人物的过程。
- 负责理解每个用户角色或虚构人物,以及它们之间的异同。
- 开发软件时,负责考虑不同的用户角色对于软件如何运行的不同偏好。
- 负责确保在识别和描述用户角色时,它们只是这个过程中的工具,不应超越作为工具之外的任何用途。
- 客户职责。P35
- 负责寻找用户(多多益善),并识别恰当的用户角色。
- 负责参与识别用户角色和虚构人物的过程。
- 负责确保软件没有关注不恰当的用户。
- 在编写故事时,负责确保每个故事都能和至少一个用户角色或虚构人物联系起来。
- 开发软件时,负责考虑不同的用户角色对于软件如何运行的不同偏好。
- 负责确保在识别和描述用户角色时,它们只是这个过程中的工具,不应超越作为工具之外的任何用途。
第4章 搜集故事
- 需求本来已经存在了,我们只要让客户给我们解释需求,然后把它们锁入一个笼子里就可以了。很多需求并不容易想到。同样,用户并不知道所有需求,所以不能单纯依靠引出。P37
- 收集需求就像拖网捕鱼一样。首先,不同大小的网用来捕获不同大小的需求。第一遍我们可以用大网眼的渔网捞一遍需求池,以此得到所有的大需求。通过这些大需求,形成对软件的整体感觉,接下来,用网眼稍微小一些的渔网得到中等大小的需求,暂时还不用顾及那些小需求。P37
- 冥界项目则承认没有一种理想的方法可以在一个单一阶段获取到所有的用户故事。敏捷过程也承认用户故事有一个时间维度:随着时间推移以及先前迭代中加入产品的故事,一个故事的相关性(relevance)会有所变化。P38
- 因为故事会随着项目的进展二演进,所以我们需要一些可以反复使用的方法来搜集故事。我们使用的技巧必须是足够轻量的,并且不咄咄逼人,可以持续地、或多或少地应用于故事搜索。一下是创建故事最有用的一些方法:P39
- 用户访谈
- 问卷调查
- 观察
- 故事编写工作坊
- 用户访谈。P39
只询问用户“你们需要什么”是不够的,大部分用户不太善于理解,更难以表达他们的真实需求。询问开放式的问题好得多,这可以让调查对象表达更深入的意见。如果问封闭式的问题,调查对象只能回答简单的是或否。同样重要的是要提背景无关的问题。从背景无关的问题开始提问,这样就有可能从用户那里获得更多样化的回答。如果从非常具体的问题开始,则很可能漏掉很多故事。P40 - 问卷调查。P41
问卷调查会是一种有效的方法,有助于收集已有故事的相关信息。若有一个庞大的用户群,那么问卷就是收集有关故事优先级信息的好方法。在需要得到大量用户关于耨写具体问题的回答时,问卷是非常有用的。 - 鉴于单向沟通的既有特点和时间滞后,我不建议在捕捞故事时使用问卷调查。P41
- 观察。P41
观察用户实际使用软件的情况。这种机会可以让你快速直接地从用户那里获得反馈,从而可以更早、更频繁地发布软件。 - 故事编写工作坊。P42
故事编写工作坊是开发人员、用户、产品客户和其他对编写故事有版主的人共同参加的会议。在工作坊期间,参与人员编写尽可能的故事。此时不对故事排优先级,以后客户有机会排优先级。我认为,故事编写工作坊是快速捕捞故事最有效的方法。至少,我建议再开始每个计划发布前举办故事编写工作坊。在通往软件发布的路上,总是可以举办更多的故事编写工作坊,但这通常是没有必要。 - 在画用户故事原型中,问一些有助于找到遗漏故事的问题,示例如下。P44
- 用户接下来最有可能做什么?
- 用户会在这里犯什么错误?
- 在这里,用户会有什么困惑?
- 用户需要什么额外的信息?
- 在故事编写工作坊期间,我们应该把重点放在数量上而不是质量上。即使最后会用电子方式保存故事,但在工作坊里最好还是用卡片。只要把想法记下来就行。最初大家觉得不好的故事经过几个小时候可能就会变得很棒,或者这会激发我们相出其他故事。另外,不要为每个故事都陷入长时间的讨论中。如果一个故事是多余的或者能够更好的故事替换,就扔掉这个故事。同样,当客户为发布而确定故事优先级时,他可以给不好的故事安排低优先级。P44
- 有时,一些参与者在工作坊中很难开头,或者卡在某个点上过不去。这时不妨看看竞争对手的产品或类似的产品。P44
- 不要在整个过程中评价某个故事好或坏。一旦参与者觉得大家只是在记录而不是评价故事,会更乐意参与。P45
- 小结。P45
- 能够引出或捕捉需求这一想法是错误的。它有两个问题的假设:用户知道所有的需求;需求一旦被捕捉,就锁定,不再改变。
- 拖网捕鱼的比喻是非常有用的:它说明了需求有不同的大小,需求会随着时间的推移变化,需要一些技巧来发现需求。
- 即使敏捷流程支持需求的后期涌现,依然需要对预期的发布进行展望并开始写下容易发现的故事。
- 我们可以通过用户访谈、观察用户、问卷调查和举办故事编写工作坊来发现用户故事。
- 使用多种方法比过度使用一种方法更能获得好的效果。
- 通过开放式、与背景无关的提问更容易获得有用的答案,例如,“告诉我你想怎么搜索工作?”就胜于“你要通过职位名称来搜索工作吗?”
- 开发人员职责。P45
- 负责理解并使用多种技巧来捕捞用户故事。
- 负责知道怎么使用开放式和背景无关的提问。
- 客户职责。P45
- 负责理解并使用多种技巧来捕捞用户故事。
- 负责尽早写更多的用户故事。
- 作为软件用户的主要代表,负责和他们多沟通。
- 了解怎么使用开放式和背景无关的提问。
- 如果需要关于编写故事的帮助,负责安排并举办一次或多次故事编写工作坊。
- 负责确保在捕捞故事过程中考虑所有用户角色。
第5章 与用户代理合作
- 对于一个项目来说,客户团队里包括一个或多个真实用户是极其重要的。虽然其他人可以猜想用户如何使用软件,但事实上,关键往往还在于实际用户。遗憾的是,我们很难有机会与实际用户一起工作。P47
- 在开发一个供内容使用的项目时,组织可能不愿理让你完全不受限制地接触一个或多个用户,缺可能让你接触用户的经理。如果用户的经理不是软件的实际用户,这其实就是偷梁换柱。P47
- 有时候,用户的经理会从中干预,并且出于自负,想在项目中充当用户的角色。她可能承认自己不是典型的用户,但她固执己见,认为自己比她的用户更知道他们需要什么。当然,在这种情况下,务必小心,不要得罪用户的经理。但是为了项目的成功,在部分围绕她的同时,也要想办法接触终端用户。P57
- 让开发经理担任用户代理,是最坏的选择之一,除非你们开发的软件就是给开发经理用的。大部分开发经理对正在开发的软件没有像用户那样的亲身经验,而且他们也不是领域专家。P48
- 让销售人员充当用户代理是危险的,这会让大家对正在开发的产品没有一个全面的蓝图。对销售人员来说,最重要的故事是哪些如果没有实现就会导致她“丢单”的故事。如果希望软件是可用的,就要通未来的用户交流。P49
- 领域专家,有时也称为主题专家,是非常重要的资源,他们对软件应用领域的了解程度对软件的成败有直接影响。让领域专家来担任用户代理的另一个潜在问题是,最终开发出的软件可能仅仅针对那些与领域专家有类似水平的用户。领域专家会倾向于将项目指向合适他们自己的解决方案上进行,但这往往过于负责,对目标用户群体而言明显是错误的。P50
- 了解市场的是营销团队,而不是用户。这会导致营销团队或者有营销背景的人更关注产品特性的数量,而轻视特性的质量。在很多情况下,营销团队可以为相关故事的优先级提高层次的知道意见,但他们往往不具备很好的洞察力,无法提供故事的具体细节。P50
- 如果以前的用户在不就前还使用过你们的软件,那么由她来担任用户代理是非常耗的。但和其他用户代理一样,应该谨慎考虑她的目标和动机是否与实际用户的完全一致。P50
- 客户是那些做出购买决定的人,他们不一定是软件的用户。P50
- 如果用培训师充当用户代理,你的系统最终只能成为一个容易培训的系统。类似的,如果你让技术支持来充当用户代理,那么你的系统最终只是使得支持工作变得较为容易。P52
- 许多业务和系统分析师是很好的用户代理,因为他们即懂技术,有熟悉软件相关的领域知识。能平衡好这些背景且努力跟实际用户沟通的分析师,通常会是非常出色的用户代理。有些分析师暴露出来的问题是,他们遇到问题喜欢空想,而不是去做调查。P52
- 访问实际用户受阻团队被告知要和用户代理一起工作,最好的方法之一是请求准许启动一个用户顾问团队(user tabsk force)。P52
- 实在不能接触到用户时,必须求助于用户代理,一种有价值的方法是使用多个用户代理。P53
- 建立客户团队有三步。P54
- 邀请真实用户加入。
- 在客户团队中确定一位“项目负责人”或“一把手”。
- 确定项目成功必须的关键因素。
- 小结。P55
- 除非用户的经理也是用户,否则她就不是合适的用户代理。
- 开发经理会试图担任用户代理,因为他们已经参与到项目每天的细节中。然而,开发经理大多不是正在开发的软件的用户,所以他们不是理想的用户代理。
- 在产品公司里,客户经常来自市场团队。来自市场团队的人经常是不错的用户代理,但他们通常关注于软件的功能数目,而不是其质量,这点必须要克服。
- 与很多不同的客户(而这些客户同时也是用户)联系的销售人员可以是很好的开发项目客户。销售人员必须避免把重点放在那些可以重新赢得已失去订单的故事上。在所有情况下,销售人员是与用户沟通的有效渠道。
- 领域专家可以成为优秀的用户代理,但必须避免一点:在为产品编写故事时,将产品开发成只适合那些与他们有相同水平的人使用。
- 客户,那些做出购买决定的让你,如果他们能与用户密切地交流,那么他们能成为非常好的用户代理。显然,如何客户自己也是用户,那就是完美的组合。
- 为了成为好的用户代理,培训师和技术支持人员必须避免仅仅关注产品中那些他们每天关心的方面。
- 本章也简短地给出了一些与用户代理一起工作的方法,包括用户顾问团队的使用,使用多个用户代理,分析竞争产品,尽早发布软件来获取用户反馈。
- 开发人员职责。P55
- 负责帮助组织机构为项目物色合适的客户。
- 负责了解不同类型的用户代理怎么考虑你们正在开发的系统,他们的背景如何影响交互。
- 客户团队职责。P55
- 如果你不是软件的用户,则要负责了解自己属于哪种用户代理。
- 负责理解自己会将哪些偏见带入到项目中,如何克服这个问题,无论是依靠别人还是其他方法。
第6章 用户故事验收测试
- 既然软件是用来实现用户的愿景,验收测试当然就应当由客户来定义。P59
- 多少测试才算多。P59
只要这些测试还在继续为故事增加价值和使它更加清晰,客户就应该继续写测试。 - 测试的是缺陷,而不是覆盖率。P61
在一个敏捷的由故事驱动的项目中,测试并不像很多团队那样是一个对抗性的活动。发现缺陷时,不该有“被我逮到了吧”这样的心态。在敏捷开发中,若有缺陷知道系统投产的时候才被发现,团队成员是不应该项目推卸责任的。高度协作的团队以及“我们共同负责”的心态防范这种事情的发生。 - 在敏捷项目中,测试的目的发现并消除缺陷,所以没有必要追求100%的代码覆盖率或测试所有边界条件。我们运用我们的直觉、知识和过去的经验来指导测试。P61
- 小结。P62
- 验收测试可以用来记录客户和开发人员讨论的很多细节。
- 验收测试记录了有关故事的一些假设,这些假设可能还没有和开发人员讨论过。
- 验收测试提供了检查故事是否被完整实现的基本标准。
- 验收测试由客户来编写而不是开发人员。
- 验收测试应在程序员写代码之前就写好。
- 如果新的测试对阐明故事的细节或意图没有任何帮助,就不用再写。
- FIT和FitNesse是写验收测试的优秀工具,它们用的是我们熟悉的表格或电子表格格式。
- 开发人员职责。P62
- 若团队觉得有需要,则负责实现自动化验收测试。
- 开始开发一个新的故事时,负责考虑更多的验收测试。
- 负责为代码作单元测试,使验收测试就不必顾及故事的每个细节。
- 客户职责。P62
- 负责编写验收测试。
- 负责执行验收测试。
第7章 优秀用户故事准则
- 在一个大型项目中,尤其是有许多用户角色的项目,确定用户故事有时让人无从下手。我发现最好的办法是考虑每一个用户角色,了解用户使用我们软件的目的。P63
- 切蛋糕。P63
当面临一个大的故事时,通常有许多方法可以将它分解成较小的故事。许多开发人员首先想到的是将故事按照技术路线分割。这样做的缺陷是,没有一个故事是单独对用户很有用的。一个更好的办法是换一种方式编写故事,每个故事都提供某种程度的完整的功能。称之为“切蛋糕”。 - 一个封闭的故事是指那种随着一个有益意思的目标的实现而结束的故事,能让用户使用后觉得她完成了某个任务。编写封闭故事其实是在相互冲突的各种需求之间权衡的结果。因为,故事也要小到能做评估,小到可以方便地安排到一轮迭代中。但故事也要足够大(这里的大指的是粒度的、高层次的和抽象的),从而避免过早捕获当下还不需要的细节。P64
- 你应专注于最需要你关注的领域。通常,这意味着要把注意力放在那些即将发生的事情上,而不是放在更远的将来才发生的事情上。对股市而言,要基于故事实现的时间跨度,以不同的层次来编写故事。P66
- 一直困扰着软件需求方法的问题之一试讲需求和解决方案混在一起。也就是说,在陈述需求的时候,也显示说明或暗示了解决方案。最常见的情况是用户界面。你应尽量让故事不包含用户界面。P66
- 在故事里包括用户角色。这样编写故事,能让用户在开发人员脑子里保持最重要的位置。开发人员不会去想乏味的、不形象的、可切换的用户,他们会联想实际的、真切的用户,开发出满足用户需求的软件。P67
- 每个故事使用下面的格式编写:P67
我作为(角色),想要(功能),以此(商业价值) - 当故事只为单一用户编写时,故事的可读性通常是最强的。P68
- 用户故事用主动语态编写时,更易于阅读和理解。P68
- 给故事卡片编号会增加无谓的流程,并导致我们去抽象地讨论需要形象化的功能。P69
- 小结。P69
- 为了确定故事,从每个用户角色使用系统的目标开始考虑。
- 分割故事时,试着将它分割成贯穿应用程序所有层面的故事。
- 试着 让故事的大小能够在使用后让用户感到可以去喝杯咖啡休息一下。
- 如果有项目领域和环境的需要,可以用其他需求搜集或文档技术来补充故事。
- 创建约束卡,将它们贴在公共的墙上,或者编写测试来确保系统没有违反约束。
- 为团队即将实现的功能编写小的故事,针对未来实现的功能编写宽泛的、高层次的故事。
- 不要让故事过早涉及用户界面。
- 实际编写故事时,要包括用户角色。
- 用主动语态编写故事。
- 为单个用户编写故事。
- 让客户,而不是开发人员,编写故事。
- 用户故事要简短,别忘了,它们的目的是提醒开发人员和客户进行对话。
- 不要给故事卡编号。
第II部分 估算和计划
第8章 估算用户故事
- 故事估算的最好方法具有如下特点。P73
- 无论什么时候获得有关故事的新信息,都允许我们改变之前的想法。
- 适用于史诗故事和小故事。
- 不需要花很多时间。
- 提供进度和剩余工作的有用信息。
- 不太精确的估算也不会有太大问题。
- 可以用来制定发布计划。
- 我个人比较偏好将一个故事点的工作量看作是一个理想日的工作。第一,相较于用连续时间估算,它更简单。用持续时间估算迫使我们考虑对时间的各种可能的影响。第二,相较于用完全模糊单位,用理想日估算故事点可使我们的估算拥有更好的依据。估算的主要目的之一是知道整个项目的工作量,所以最后我们总是要将估算换算成时间。显然,相较于用完全模糊单位,用理想时间更简单。P73
- 故事估算应该由整个团队集体完成。第一,还不确定团队中谁负责完成这个故事,所以应该把故事分配给整个团队而不是某个人。第二,团队决定的估算可能比个人估算更有用。P74
- 估算。P74
估算方法把所有参与估算的客户和开发人员聚集在一起。带上故事卡和一些额外的空笔记卡。发给每个参与者一些空卡片。客户随机抽取一个故事,读给开发人员听。开发人员根据需要尽可能多发问,客户要尽其所能解答。如果客户不知道答案,可以先猜猜看,或者要团队推迟估算这个故事。 - 程序员估算一个故事时,他们应考虑完成这个故事需要做的所有事。他们要全盘考虑测试代码,和客户讨论,可能帮助客户计划或自动化验收测试等诸多因素。P74
- 估算。P75
每个开发人员在卡上写下一个估算值,先不要给其他人看。大家都写好估算值后,所有人翻开他们的卡片或者拿起展示给所有人看。这时,估算值很有可能相差很大。这其实是件好事。如果估算值不同,估算值高的和低的再解释一下估算依据。值得注意的是,这时不要互相攻击对方,而是耐心听取他们的想法。 - 三角测试。P76
在做了几个估算后,我们可以(而且必要)对估算做三角测量。具体做法就是在估算一个故事时,根据这个故事与其他一个或多个故事的关系来估算。假定一个故事估算为4个故事点,第二个故事估算为2个故事点。把这两个故事放在一起考虑时,程序员应该都同意4个点的故事大概是2个点的故事的两倍。 - 使用故事点。P76
在一轮迭代结束时,团队计算已完成的故事点数。因为即将到来的迭代也是同样的长度,这个点数可以作为下轮迭代将完成的故事点数的预报。 - 小结。P79
- 用故事点估算故事,故事点是故事复杂度、工作量或工期的相对估算。
- 应由团队估算故事,估算属于团队而不是个人。
- 通过和其他估算进行比较来进行三角测量。
- 团队是否使用结对编程对故事点估算没有影响。结对编程影响的是团队的速率,不是他们的估算。
第9章 发布计划
- 我们想在什么时候发布。P81
理想情况下,开发人员和客户可以谈一个日期范围,而不是一个具体日期。如果一个团队做发布计划时能以一个可接受的日期范围为起点,那么他们的发布时间将更灵活。例如在6或7轮迭代之后,应该有最基本的功能。 - 希望再发布中包含哪些功能。P82
为了计划一个发布,客户必须排列故事的优先级。我们可以借用来自DSDM的方法,它是另一种敏捷过程。DSDM包括一个排列优先级的方法,称之为莫斯科(MoSCoW)规则。- 必须有(Must have):指系统的基本功能。
- 应该有(Should have):指很重要但短期内有替代解决方法的功能。如果项目没有时间约束,通常认为应该有的功能是强制性的。
- 可以有(Could have):指如果没有时间就可以在发布中不予考虑的功能。
- 这次不会有(Won't have this time):客户期望拥有但同时承认需要在后续发布中实现的功能。
- 排列故事优先级。P82
我们可以通过多个维度来为故事排优先级。可以利用的技术要素如下。- 故事不能如期完成的风险。
- 推迟实现一个故事时对其他故事的影响。
- 故事对于广泛用户或客户的重要性。
- 故事对于少部分重要用户或客户的重要性。
- 故事与其他故事的内聚性。
当客户和开发人员对这个顺序有不同意见时,最后每次都应该是客户说了算。
- 大家一直再争论一个问题,即对一个项目来说,应该先做最有风险的部分,还是先做最有价值的部分。风险驱动开发的主要领导者也许是巴·里鲍依姆(Barry Boehm),他的螺旋模型(spiral model)着重在早期消除风险。而另一个方向的领导者是汤姆·吉尔伯(Tom Gilb),他提倡先做“油水最多”(“juicy bits”)的部分。P84
- 敏捷方法旗帜鲜明地支持先做最有价值的部分。这让敏捷项目能够避免过早地解决风险,同时也推迟了可能并不需要的一些基础性代码的开发。赞同先做最有价值的部分,还能使项目可能尽早发布,那时只提供最有价值的功能。P84
- 即使以价值优先为导向,我们在排列故事优先级时任然需要考虑风险。许多开发人员倾向于先做风险最高的故事。有时这是恰当的,但这任然必须由客户决定。然而,在排列故事优先级时,客户应该考虑技术团队的意见。P84
- 选择迭代长度。P86
开发人员和客户共同选择合适他们的迭代长度。迭代长度通常为1至4周。短迭代允许项目更加频繁地做出调整,项目进度也会更加透明;但是每轮迭代会有少许额外开销。假如不确定迭代长度,请选择段迭代而不是长迭代,使用长迭代更容易犯错。 - 初始速率。P87
- 使用历史值。
- 执行一轮初始迭代,使用那轮迭代的速率。
- 猜测。
- 小结。P88
- 在计划发布时,有必要知道客户预期的大致发布日期和故事的相对优先级。
- 故事应该以明确的顺序排列(第一个、第二个、第三个,等等),而不是利用诸如“非常高、高、中等”模糊顺序的分组。
- 故事的优先级由客户确定,但也要考虑开发人员的想法。
- 使用速率将以理想日为单位的估算转换成日历日。
- 估算团队的初始速率是很有必要的。
第10章 迭代计划
- 整个团队通过举行迭代计划会议来为下一轮迭代做计划。迭代计划会议的一般内容如下。P91
- 讨论故事。
- 从贵中分解出任务。
- 开发人员承担每个任务的职责。
- 讨论过所有故事,并且接受所有任务后,开发人员单独估计他们承担的任务,以确保他们不会做出过于乐观的承诺。
- 讨论故事。P91
团队获得一个已经排好优先级的故事集合,以此作为迭代计划会议的输入。正如程序员可能改变他们对实现一个故事难度的看法,客户一样可能改变她对故事优先级的想法。迭代计划会议是客户为团队调整故事优先级的最佳时机。 - 分解任务。P92
尽管故事的确可以小到作为工作单位,但将它们分解出更小的任务,一般更符合项目的需要。首先,对很多团队来说,实现故事的开发人员不止一个。其次,故事是对用户或客户有价值的功能描述,它们并不是开发人员的待办事项(to-do list)。把故事分解成任务常常是有用的,因为这有助于发现那些可能会被遗忘的任务。 - 敏捷过程为人诟病的地方之一,是它没有像瀑布过程那样的前期设计步骤。这是事实,敏捷没有前期设计阶段,敏捷过程的特点是做频繁的短期设计。P93
- 从故事分解任务时,使用一下准则。P93
- 如果故事的某个任务特别难于估算,就把那个任务从故事的其余任务中分离出来。
- 倘若有些任务可以很容易安排给多名开发人员共同完成,就分割它们。
- 若有必要让客户了解故事某一部分的完成情况,可以把那部分拿出来作为一个任务。
- 承担职责。P94
团队要有一种“同舟共济”的心态。而且,在迭代快要结束时,如果有开发人员不能完成他接手的所有任务,团队中的其他成员应该尽量用于承担。
第11章 测量并监控速率
- 不能将部分完成的故事也计算在速率中。首先,一个显然的问题就是没法计算故事已完成的百分比。其次,不想使用带小数的值为速率引入错误的精度。第三,没完成的故事通常并不能给用户或客户带来任何价值。第四,既然一个故事大到包含一个影响速录的子故事,那只能说明这个故事确实太大了。最后,我们尽量避免许多故事90%完成,没有多少故事100%完成的情形。P98
- 计划速率和实际速率。P98
监测实际速率与计划速率的偏差,或者说,是否需要采取什么措施保证合理的速率,这是很重要的。一个比较好的方法是为每轮迭代画出计划速率和实际速率。 - 迭代燃尽图。P100
另外一个监控进展的好方法就是迭代燃尽图(Burndown Chart)。迭代燃尽图展示了以故事点表示的在每轮迭代末剩余的工作量。
第III部分 经常讨论的话题
第12章 故事不是什么
- 小结。P117
- 用户故事有别于IEEE 830软件需求规格、用例和交互设计场景。
- 不管预想得那么全面,我们都无法事先完全定义一个完整的具有相当规模的系统。
- 在定义需求和用户早期频繁接触软件之间,有一个有价值的反馈循环。
- 考虑用户的目标比列出方案的特性更重要。
- 用户故事与用例场景类似。但用例往往任然比单个故事要大,更容易包含关于用户界面的嵌入式假设。
- 此外,用户故事与用例的完整度和寿命不同。用例比用户故事完整得多。用例存在于整个开发过程中。用户故事往往只是暂时的,它们的生命周期仅仅限于开发它们的迭代中。
- 用户故事和用例以不同的目的编写。用例被编写成方便开发人员和客户讨论并达成共识。用户故事编写成方便计划发布,并用于提醒需求细节的讨论。
- 不像IEEE 830规格和用例,用户故事不是分析活动的产物。相反,用户故事是进行分析的支持工具。
- 交互式设计场景比用户故事具体得多,它们提供的细节类型也不同。
- 典型的交互式设计场景比用户故事大得多。一个场景可以由多个用例组成,相应地,它可以组成许多用户故事。
第13章 用户故事的优势
- 使用用户故事到底带来哪些好处。P119
- 用户故事强调口头沟通。
- 人人都可以理解用户故事。
- 用户故事的大小适合做计划。
- 用户故事适合于迭代开发。
- 用户故事鼓励延迟细节。
- 用户故事支持随机应变的开发。
- 用户故事鼓励参与性设计。
- 用户故事传播隐性知识。
- 小结。P127
- 用户故事促使我们重视口头交流。与其他完全依赖书面文档的需求方法不同,用户故事认为开发人员与用户之间的交谈有重大的意义。
- 重视口头交流这一转变提供了迅速的反馈周期,往往能促成对需求的充分理解。
- 开发者与用户都能理解用户故事。IEEE 830软件需求规格往往容易充斥着太多的技术或商业术语。
- 用户故事的典型范围规模比用例及场景小,但比IEEE 830文档大,这个大小适合做计划。计划、编码及测试,都可以不再需要合并或分解故事就能完成。
- 用户故事适合于迭代开发,我们很容易从一个史诗故事入手,并在后来需要时把它分成多个小故事。
- 用户故事鼓励延迟细节。可以很快地写出独立的用户故事,而且写出不同大小的故事也很容易。对于不太重要的或者一开始不会被开发的需求,我们可以选择先用史诗故事来代表,而其他故事包含有更多的细节。
- 故事鼓励随机应变的开发。在此方式中,随着不断地发现机会,团队视线能迅速地在高层及低层细节思考间来回切换。
- 故事提升团队内隐性知识的水平。
- 用户故事鼓励参与性设计。与经验性设计不同,用户成为软件行为设计的活跃的参与者,做出有价值的贡献。
- 虽然使用故事有不少的好处,不可否认也有一些缺点:大型项目中难以组织好成千上万的用户故事;有时候需要额外的文档以实现可追溯性;尽管面对面的沟通大大促进隐性知识的共享,但在大型项目中,单单依赖这种交谈难于实现有效的扩展来完全替代书面文档。
第14章 用户故事不良症兆一览
- 小结。P134
- 故事太小:小故事的规模估算十分依赖于故事实现的顺序。实现顺序不同,规模估算值可能也有很大的差异,从而导致故事估算和计划出现问题。
- 故事互相依赖:两个甚至多个故事之间相互依赖,以至于很难把单独的故事放入迭代中。
- 镀金:指的是开发人员实现了不需要的功能。可能有几个原因,首先,很多开发人员总是希望给客户带来惊喜。其次,在敏捷软件开发项目总是采用基于故事驱动的短迭代模式,开发人员总能感受到需要不断生产的压力。镀金功能使得开发人员得到一定程度的解脱。最后,开发人员总是愿意在项目中留下自己的印记,添加一些“宠物功能”就是一个种留下自己印记的方式。如果项目组中的卡法人员花太多的精力去开发镀金功能,一个有效的解决方法是提高项目组中每个人的任务可见性。
- 故事中包含太多的细节:把故事写到小卡片上的一个好处是在小卡片上只能记录下很有限的东西。避免花太多的时间去写故事而不去讨论故事。
- 过早包含用户界面细节。
- 想得太远。
- 故事划分太过频繁。
- 很难为故事安排优先级。
- 客户不愿意写用户故事,为故事安排优先级。
第15章 Scrum与用户故事
- ScrumMaster更多的是为Scrum团队服务,而不是指手画脚。ScrumMaster主要负责为团队排除障碍,保证开发的顺利进行,确保整个团队按照Scrum的简单规则进行开发。P137
- Scrum的主要规则。P139
- 在Sprint开始的时候召开Sprint计划会议。
- 每个Sprint必须发布可以工作的、经过测试的代码,这些代码能够完成对最终客户有价值的一些功能。
- 产品负责人为产品Backlog排列优先级。
- 团队一起决定一轮迭代完成多少故事。
- 在任何时候都可以向产品Backlog中添加故事,或者重新排列优先级。
- 每天有一个Scrum短会。每个项目成员回答三个问题:我昨天做了什么?我今天打算要做什么?我有什么困难?
- 只有团队成员能在每日Scrum简会中发言,其他人包括对项目感兴趣的观察者或利益相关者都不能发言。
- 在Sprint结束时的Sprint评审会议中,团队会演示完成的成果。
- 团队演示的是可以工作的软件,而不是幻灯片。
- 准备Sprint评审会议的时间不得超过两小时。
- 小结。P144
- Scrum是一种迭代和递增的过程。
- Scrum每30天一轮迭代,成为Sprint。
- ScrumMaster相当于传统的项目经理,但更像是领导者和组织者,而不是经理。
- 一般的Scrum团队包括4~7个开发人员。
- 产品Backlog是一个待开发的工鞥呢需求列表,里面的条目要么还没有实现到产品中,要么还没有计划再当前Sprint中开发。
- Sprint Backlog是一个团队承诺在当前Sprint完成的任务列表。
- 在极限编程里面的客户角色,在Scrum中称为产品负责人。
- 产品负责人负责给产品Backlog排列优先级。
- 在Sprint的开始,团队从产品Backlog中选择下一个Sprint要完成的任务。
- 在每日Scrum简会中,每个团队成员需要回答三个问题:我昨天完成了什么?今天我要做什么?我碰到了哪些问题?
- 每个Sprint都要完成一部分可以潜在交付的产品功能增量。
- 在Sprint结束时,团队再Sprint评审会议上演示所完成的功能。
第16章 其他话题
- 小结。P154
- 非功能性需求都可以通过创建约束卡的方式来处理。假如系统的需求比这些更复杂,但无论其他格式还是方法,只要它能充分表示那些需求,就可以用作用户故事的补充。
- 笔记卡和软件系统都不是 适用于所有情况下编写故事的最佳方式。使用适合项目和团队的工具。
- 迭代过程会导致用户界面的反复变动。习惯于特定界面的用户,不会喜欢用户界面变动,因为这会影响他们已经学会的操作软件的方法。可以考虑加入一些敏捷版以使用为中心的设计实践,以避免用户界面的发福变化。
- 一旦故事完成,撕毁故事卡会有一定的乐趣。但同样也有保留卡片的理由。宁可谨慎一些,保留故事。
- 把小的缺陷报告用一个封面故事卡装订在一起,并把它们当成一个单一故事。
第IV部分 一个完整的实例
建议必读