我所经历的敏捷开发

2017-01-23 jude 更多博文 » 博客 » GitHub »

原文链接 http://judes.me/life/2017/01/23/my-so-call-agile.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


以下关于敏捷开发的内容,只是我个人经历和感想,没打算说点“正确”的话,觉得我说的错得离谱,大可以认为我经历的是假的敏捷开发 ^_^

我来到现在的公司才第一次接触敏捷开发,之前对敏捷开发一无所知。

说起敏捷开发,网上已经有一大堆复杂抽象的概念,在实际工作当中能接触到的有典型特征的几件事情就是:每天站立会议、头脑风暴形式的需求讨论会议、测试用例设计会议、code review、迭代回顾等等。

每天站立会议的形式是让每一个人当着大家的面说一下自己昨天完成了什么用户故事,今天计划完成什么用户故事,以及遇到了什么问题,需要谁的帮助等等。会议方便大家了解、监督彼此的进度,之所以采取站立的形式,是要控制开会的时间不要过长。

用户故事来源于客户的需求以及整个产品和研发团队对客户需求的分析,分析的过程就是需求讨论会议,参与会议的人有客户(最理想的情况)、产品经理、整个研发团队。大家对客户提出的需求进行讨论、头脑风暴,最终整理得出一个个的用户故事。

接下来就是测试用例设计会议。参加会议的人有产品经理以及整个研发团队。会议上面大家对每一个用户故事提出各种可能的用例,每一个用例的形式大致就像这样:谁在什么前提下依步骤做了什么操作,操作成功的时候他会得到什么回应,操作失败的时候她又会得到什么回应。在验收迭代产出的时候,验收人员根据测试用例来判定测试是否通过。

研发人员根据测试用例,首先写好测试用例,然后实现功能代码,确保所有的测试用例都顺利通过。之后请其他研发人员做 code review 。review 通过之后才能提交代码。

迭代回顾安排在每一次迭代完成之后。让整个团队,包括产品经理和研发人员总结在这一次迭代当中有什么事做得好的,有什么事做得不好,以及有什么事可以做得更好。在回顾当中,针对做得不好的地方提出可行的改善方案,在下一次迭代当中实行此方案。

以上所说,就是较为理想的敏捷开发。

最初我们在站立会议上使用白板和便签来描述每一个人计划要做的,正在做的,已经完成的用户故事。后来,我们发现把用户故事写在便签上面,查看用户故事,以及在迭代回顾总结自己所做的事情的时候并不方便,所以后来我们直接就用了 jira 来录入和管理每一个人领取的用户故事。

用户需求讨论会议上,虽说是头脑风暴,但实际上往往只要那么几个人愿意开动脑筋去思考用户提出的具体的某一个需求背后到底隐藏着怎么样的真正的需求,或者说我们交付出去的产品怎么样才能更好的满足用户的需求。

测试用例设计会议,我们只坚持开了几次,之后的测试用例就让负责完成每一个用户故事的研发人员自己去写。我一直觉得测试用例是非常重要的:软件的某一个行为究竟是特性还是碧油鸡(bug),就由测试用例决定。之所以只能坚持几次,我想是因为负责纪录测试用例的人打字速度不够快吧:如果有十个人在会上轮流提出一个测试用例,但只有一个人负责记录,那么当那个人写第一条测试用例的时候,其余九个人就只能等着,对他们来说这段时间浪费了。

敏捷开发要求研发人员实行测试驱动开发,测试驱动开发有几个步骤:第一,在编写任何功能代码之前先编写测试代码;第二,只编写刚好体现一个失败的测试用例;第三,只编写刚好让失败的测试用例通过的功能代码。

在实践测试驱动开发的过程中,我始终不能接受上面的三个步骤。在写好能运行起来的代码之前,我很难给这段代码编写相应的测试用例,因为:第一,在什么都没有的时候,我不知道测试的边界在哪里;第二,在功能代码有雏形之前,代码本身会频繁变动,这时候我并不在乎代码本身是否正确,但一旦写了测试代码,我都必须要在每一次改动之后相应地修改测试代码,这样会不断地打断开发人员的思路,影响开发效率。

但是我很认同测试对软件质量的是至关重要的,所以最终采取的是:先编写功能代码,编写功能代码的时候,先让代码能跑起来,再让代码“看起来正确”地跑起来,然后编写测试代码,测试代码要覆盖相应的测试用例,编写好测试代码之后,再着手修正、重构功能代码。

确保所有测试用例都跑通过之后,让其他研发人员帮忙检查代码,也就是 code review 。在实行代码检查的时候遇到很多困难:比如说,在研发人员忙的时候,让他替你检查代码,他通常是不愿意的,他要么是直接拒绝你,要么是敷衍了事。还有一种情况就是,检查的人与被检查的人对某一段代码的实现有不同的意见,而且都不能说服对方。这些都会导致研发人员不愿意进行代码检查,我个人的做法是在编写具体的功能代码之前,首先向其他人描述自己的大概实现思路,确保在大方向上不会出现偏差,找人检查代码的时候,如果他忙就找另外一个人(就算这个人对这个功能一无所知也没有问题),用最简单的语言让他明白你实现了一个怎样的功能。

以上所说,是我们崩坏之前的敏捷开发,说说崩坏后的景况:

如今,只有每天站立会议和代码检查还能维持下来,需求讨论会议便成需求了解会议,测试用例设计会议早就不存在,测试代码也早已成为研发人员的包袱:新开发的功能影响了已有的功能,导致已有的测试失败,但是并没有时间修改正确,当大部分测试代码都失败的时候,研发人员已经不再指望测试代码来保证功能的正确性;迭代回顾也已经很久没有开,但也没有人感觉缺少了什么东西。

回顾近两年所经历的敏捷开发,我总结出敏捷开发是一整套对所有参与其中的人员有着高要求的规范:他要求所有人主动承担整个产品的责任,人与人之间要密切沟通交流,最重要的是要求尽早的交付给客户有价值的能满足用户需要的产品。

我们的敏捷开发之所以会崩坏,就是因为我们一直都没有找到对客户有价值的功能点,没有找到有价值的功能点就不确定该先做哪些功能,所以全都做,因此就不能尽早的交付给客户。经历了近两年的失败,无论是产品经理还是研发人员已经对公司在这个方向上的探索不抱希望:产品经理辞职,研发人员从主动了解需求、提出建议到被动接受、执行需求。同时,因为一直没有找到主要的功能点,业务方向经常改变,导致功能代码到了需要重构的时候,却不得不在此基础上实现新的功能代码,功能代码都没有时间来得及好好想想如何实现,测试代码的通过与否就更不在话下了。