这样带来了两个很有趣的问题:

如果团队同时在实现多个故事,该怎么办?
如果其他团队也正在向主干发布内容,又该怎么办?
我们还是一个接一个地来看这些问题。

如果团队同时在实现多个故事该怎么办?
如果团队每次实现一个故事,将代码发布到主干中并不算什么大不了的事情。只要这个故事相关的代码在工作分支上完成实现并通过测试,我们把所有的相关内容从工作分支上复制到主干上可以了。搞定!

先等一下。如果团队中同时开发多个故事呢?如果“开户”故事完成了,而“存款”还在进行中呢?

如果我们在这个点上向主干进行同步,会将尚未完成的“存款”故事同步进去,这时它还不能发布呢!而且违反了主干的版本控制方针!

当然,我们可以等到“存款”故事完成。

(等待……)

好了,现在“存款”故事完成了!太棒了!等一下……现在有人开始开发“取款”用户故事了!没错!同样的问题又发生了!

如果 “存款”故事的一个测试失败了,很难知道是因为“存款”故事相关代码造成的,还是由于检入同一分支中并且部分完成的“取款”故事相关代码的原因。

等待无法起到任何帮助作用。这样实际上是在滚雪球,期望在未来某个假设的时间点上所有的故事都可以完成(如果这样的情况真的能够发生的话),而且可以进行一次大规模的发布。

上述是一个非常普遍的问题。我们该怎么做呢?

下面是一些应对之策:

不要做过多的并行开发。要力图将团队的注意力每次都只放在一个故事之上。
如果在“开户”完成之前有人准备开始“存款”相关的工作,要等到“开户”彻底完成之后再检入“存款”相关代码。或者可以将“存款”相关的代码检入到一个临时的分支之中,如果你喜欢操作多个分支的话。
如果在“开户”完成之前有人准备开始“存款”相关的工作,可以让他先从一些相对安全和不可见的UI元素等部分开始,这些东西的变化不会影响到整个分支的可发布性。比如,“存款”需要开发一些新的代码以及对一些旧有代码的修改,可以先实现新的代码(新的方法、新的类、新的测试等等),而不是先去修改已有代码。如果“存款”需要新的GUI元素,那让它们先不可见。等到“开户”故事完成而且发布到主干上之后,我们可以开始实现“存款”的剩余代码了。
下面是一个合适的规则集:

任何针对优先级高的故事开发的人都是“国王”。
团队其他的任何人都是“仆人”。
要是你想成为“国王”,试着找路子帮助完成高优先级故事的相关工作吧。
“国王”任何时候需要帮助,“仆人”必须马上提供相应的服务。
“仆人”不能打扰“国王”的工作。
“仆人”不能向工作分支中检入不可发布的代码。“国王”可以检入任何他想要检入的东西(当然,只要他不违反分支方针即可)。
目前优先级高的故事一“完成”,任何开始下一个高优先级的团队成员成为了“国王”。
你甚至还能为团队争取到一些王冠饰品呢。:o)

总体来说,很多团队都会过高评价同时实现多个用户故事的效果。这样做从开发速度上说感觉好像不错,但却只是一个幻象;因为它将有风险和消耗实践的编码工作推到了后??包括合并、集成与测试等工作。

这是Scrum团队应该保持小规模的原因(少于9个人)??这样他们可以紧密协作而且将注意力集中于自己的工作成果之上。如果任何人都在独立开发自己负责的用户故事,那大概不会有多少协作的情形发生了。当然可以有人为将来做计划,为下一个故事做准备并做一些实现工作。但是在任何时候,团队的主要工作努力都要放在优先级高的故事上。

多个团队是不同的情况了。如果很想并行实现多个故事,那不妨创建多个团队。我们不久后会看到如何具体操作。首先我想讨论下关于回归测试,以及分叉代码的相关话题。

完成包括回归测试在内的工作
当一个故事“完成”后,我们会把它移入到“完成”一栏中,并将相关内容从工作分支拷贝到主干中。主干必须一直保持可发布状态。此处有一个重要的暗示。

规则:任何接触到主干的人,必须保证整个主干保持可发布状态??包括之前的全部功能!

实际上,这条规则意味着:对故事A的测试,同样包括运行之前实现的故事的全部相关回归测试。如果上传代码后,故事A没有问题,但是之前故事的测试却通不过了,这是不行的。

稍等。这是不是有点不合理啊?每完成一个故事要运行所有的回归测试?

嗯,首先我没有说运行所有的回顾测试。我是说所有相关的回归测试。我们已经有了一个干净而且可发布的主干作为基础,现在只是要添加一个故事而已!这是一个很小的增量变更。如果回归测试可以自动化完成,我们可以全部运行了。要是有需要手工完成的回归测试,那我们要有选择性了。

后还是归结到了对风险vs成本的权衡之上。对于每一个手动的回归测试,我们应该评估运行它的成本(比如需要多少工作量来完成测试),同时评估发现任何重要缺陷的可能性,对二者进行权衡。当然还要加入自动化该测试的成本。:o)

分叉代码(合并冲突)
假设我正在兴高采烈地编写调用Widget类的代码,我却不知道团队成员Jim在一个小时之前进行重构时移除了Widget类。现在我们有了< b>分叉代码。在花费更多时间编写其他调用Widget类的代码前,我希望尽早发现类似问题。

规则:持续不断地(等同于尽早)将你的代码同步到工作分支中。