我在ThoughtWorks中的敏捷实践

Posted 袁慎建@ThoughtWorks

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我在ThoughtWorks中的敏捷实践相关的知识,希望对你有一定的参考价值。

此文章同时发表于InfoQ

项目回顾

项目背景

E项目是一个在线的物资跟踪监控系统。由ThoughtWorks团队为客户提供的一套完善的软件交付服务。

该系统为资助物资的跟踪与监控提供了完整的网络解决方案。整个流程涵盖了客户对物资来源的管控、库存管理、物资下发与跟踪、客户与IP(Implementing Partner,合作伙伴)的协作沟通、IP对运输结果的反馈(生成报告,警告通知,短信互动,邮件通知),以及IP对物资的二次分发后的记录跟踪与监控。

该项目属于海外独立交付项目,整个开发过程由ThoughtWorks团队负责管理。好了,项目信息只能透漏这么多了,不然客户要找我打官司了。


成员背景

ThoughtWorks提供完整的交付团队(PM, BA, TL, QA, DEV, UX),团队为颇具代表性的敏捷团队,规模10人左右。客户团队主要接口人3位。

ThoughtWorks团队成员,犹如一架生猛的战斗机:PM英文一流,敏捷开发管理相当到位,因为看了上万本脑残小说,时不时就用到了生活中来。TL拥有7年以上的开发经验,7年之痒,什么,不用说都懂的。TL还富有学习激情和被黑精神,黑历史墙列满了他的关辉血泪史。QA被誉为IT界的福尔摩斯,DEV都休想逃过她敏锐的鼻子(怎么是鼻子呢?太陶醉了吧,这是境界!),最后,就是'苦逼'的DEV,也就是以程序员自居的我们。

我们每个人特点各不相同,但有一点神似:专业,责任心,追求卓越

我们团队还有一个workout的文化特色,向⬇️看:

PS:我们的workout自开始之日到项目交付之期,不曾落下过一天,且收到良好的反馈。即便团队成员分开了,每个人都能将运动精神传播下去,乃至源远流长…


技术背景

我们是一个全功能团队,人人身怀敏捷开发领域的知识和技能,且有一定的经验积累,所以可以说我们天生敏捷,在开发过程中大家都能高效地分工合作。

再说技术栈,项目使用的主要技术栈是Python, Django, AngularJs, PostgresSQL, Docker。而我们DEV在进入这个项目之前,擅长的技术栈是Java, Springboot, C#, android, jQuery


敏捷实践

项目之所以成功交付,核心在于人,而良好的敏捷流程与实践也是不容忽视的。

早在2001年,17位追求卓越的志愿者聚集在美国犹他州雪鸟独家圣地,讨论一个新的软件开发趋势,它被称作轻量型软件开发过程,后来他们将它定义为敏捷,并且发布了敏捷开发宣言:一种把以人为本、团队合作、快速响应变化和可工作的软件作为宗旨的开发方法。敏捷宣言可以总结为四句话:

个体与交互    优于  流程与工具
客户协作     优于  合同谈判
响应变化     优于  遵循计划
可工作的软件  优于  面面俱到的文档

也就是说,尽管右项有其价值,我们更重视左项的价值。

敏捷开发的核心就是在一个高度协作的环境下,不断的通过反馈来进行自我调整和完善。重点强调的是协作反馈,协作体现在团队与客户之间的协作,团队成员之间的协作。反馈则是在开发中的任何环节,包括代码质量、自动化测试、部署、项目进度、需求变更、客户验收等,而且反馈越快越好。有句土耳其谚语这么讲的:"不管你走了多远,错了就要重新返回",所以我们越快得到反馈,就能越早确认自己有没有走错路。如果没有错,我们会更加充满信心。反之,及时做出调整,让浪费最小化。

项目中所涉及的敏捷实践主要围绕迭代进行,用一张图概括:

可以总结出以下几点:

  • Iteration通常始于IPM ,止于Showcase。
  • 每天都会发生事件有Standup 。
  • Pair、TDD、Code Review穿插在日常Coding中。
  • Story kick-off之后,该Story就进入了开发环节。
  • CI属于基础设施,通常在一个名为Iteration0的迭代完成,也就是正是开发开始之前就应该完成CI的搭建。
  • Retro较长一段时间才进行的活动,根据实际情况,1个月或两个月举行一次。
  • Regular catch up with client也会因项目而异,Daily或者Weekly,甚至某些项目可以省略该项活动。

敏捷的宗旨是减少浪费,所有的敏捷实践也都是围绕着高效协作快速反馈这两个核心理念展开。


IPM

IPM(Iteration Plan Meeting),迭代计划会议主要是跟客户保持沟通与信息更新的一个会议。

敏捷宣言里面有一条:客户协作优于合同谈判。在Scrum团队中有一个角色叫做产品负责人,Ta的核心职责是确保业务需求的清晰和透明,保证开发团队对业务有足够的了解,并将这些待完成的业务需求(Story)按照优先级排列出来,按照任务卡的方式来驱动团队的开发。并在客户需求有变更后能够第一时间告知团队以做出调整。

在我们团队中,这个角色就是一开始提到的BA。她是IPM主要参与人,另外还有Tech Lead会一起参与讨论(团队中每一个人成员都是可以参与进来的)。IPM按照团队指定的迭代的周期,通常是两周,每隔两周跟客户接口人一起约一个时间,主要讨论以下几个方面的内容:

  • 下一个迭代的Story。
  • 对下一个迭代的期望。
  • 团队的人员可用性。
  • 风险的评估总结。

通过这种会议,能够让客户对我们团队状况有一个清晰的了解,而且客户对我们下一个迭代要做的功能有了整体的把控,一起设定好期望,这样也会大大降低风险。

IPM的主要产出是下一个迭代中完成的Story,这些Story即为下一个Story要完成的目标,我们通过敏捷看板工具来管理它们,例如下图mingle上位于Backlog栏中的Story:


Regular catch up with client

跟客户建立信任关系是合作的基础,而让客户保持愉悦,也是项目成功交付的助推剂。

Regular catch up with client,即 定期跟客户进行沟通,双方共同商议一个时间(工作时间最佳),一起开个短暂的小会,时间上的成本较低。

Catch up的主要参与人员是BA(PM)和TL,通过于客户方Face2Face会议或者online会议进行一个短暂的沟通,沟通内容主要涉及:

  • 我们团队昨天的更新.
  • 客户昨天的更新
  • 确认Story。如果有变更,能及时作出调整。
  • 提醒客户使用我们开发出来的功能,以便我们尽早得到反馈。
  • 一些节日的问候,嘘寒问暖,表达我们团队的关怀。

因项目而异,Catch up实践可以大体分为两种:

  • 针对Onsite项目Face2Face形式。因为跟客户在一起工作,就可以较为高效地组织Face2Face的会议,实践证明,Face2Face是效率最高的一种形式。
  • 针对独立交付项目的Online形式。因为地点、时差等原因,适当调整Catch up的频率,另外选择一个便捷可靠地工具(例如:Fuze, GTM, Skype等),提前设置好环境并分享给客户相关人员。

通过与客户进行定期的沟通,产生的价值主要体现在客户信任和客户关系方面:

  • 首先,让客户有非常强烈的参与感,以及让他们对项目整个进展的把控(他们会觉得自己才是项目的主导者),增强他们的信心以及对我们的信任。
  • 其次,让客自己决定功能实现以及及时验收功能,降低了需求变更和打回的风险。
  • 最后,则是润滑剂了,能够在客户良好的信任的基础上,保持合作关系的轻松愉快,这会为项目的成功交付使上劲。

并不是每一个项目都会有这个实践,有些独立交付的项目,他们每日站会的时候客户也会参与进来,就不需要额外单独的时间去做这件事情了,而有些项目,因为特殊性,客户可能不希望这么频繁的Catch up,这时候需要团队灵活变通,与客户一起商讨出一个合适的时间周期,做出一些权衡,让客户自身觉得舒服。总之,Keep住的一点是:保持跟客户的信息沟通,尽可能早的得到客户的反馈,保持良好的客户关系


Standup

Standup是一项成本小收益大的活动,做好它是敏捷的第一步。

Standup,就是每日站会。我听过一个有趣的事情:在敏捷开发方法兴起的时候,很多传统开发模式的团队跃跃欲试,他们选择从Standup切入。然后每天早上上班后,大家聚在一起开个会(站着、坐着都有),然后该怎么做还是怎么做。他们会对别人说,我们在搞敏捷开发…

没错,Standup就是团队在一起快速地开一个会,大家挨个的更新一下自己的状态,更新包含以下几个方面:

  • 昨天完成的工作。
  • 今天计划做什么。
  • 面临什么阻碍。
  • 自己手头Story的进展。
  • 是否存在技术风险。

既然是快速的会议,Standup的时间就不宜过长,建议5~15分钟。最好是站着开会,因为研究表明,当人们坐着开会的时候,会议的时间会被无形中拉长。Standup的时间安排在工作时间开始后的半个小时最佳(比如9:00上班,9:30开始),这样大家就不用一到公司就急急忙忙的参加Standup,大家有个缓冲的时间,比如说设置电脑,泡咖啡,沏茶,整理今天的todo list等。

没有什么特殊原因的情况下,确保团队成员都要参加,如果一些人因为特殊原因经常不按时到,适当调整Standup的时间,但也不宜太晚。

而对于规模很小的团队(3~5人),也强烈建议执行Standup,因为它的成本真的很低。

或许有人会觉得:大家天天都在一起工作,沟通如此方便,何必要这项活动? 这有点深处酒巷中不觉酒香的味道了。站会能够给团队带来的价值不容忽视:

  • 让大家进入一天的工作状态。
  • 清楚自己的Story的进展,提醒自己把握好时间,或者激励其他成员的开发进度。
  • 让团队成员知道项目其他地方的进展。
  • 如果谁遇到不好解决的问题,可以将问题抛出来,大家一起积极讨论解决方案,也能寻求其他人员的技术支持。
  • 避免在重复造轮子而耗费时间,让大家知道目前团队中可供复用的解决方案。
  • 帮助Team Leader了解哪些领域需要更多的帮助,从而更好地分配资源。

下面是我们团队的Standup:

PS: Standup的时候,选一实物作为Token,发言时拿着Token。上图中我们选择了瑜伽球作为Token,逗比们说:健身无处不在~


Story kick-off

在一个Story开始前,确保BA, QA, DEV对Story的理解达成一致,并严格按照AC来验收。当然,前提是Story本身是不容置疑的。

Story kick off,指的是对某一个Story进行开卡,也就是启动该Stroy,从而使其进入开发阶段。Story kick off的时候,通常需要三个角色一起参与:BA、QA以及要开发该Story的DEV。

Story由BA预先写好,并通过专业的敏捷管理工具进行管理。DEV在kick off的时候,BA会给DEV讲解这个Story要完成的功能,以及它的AC。DEV如果对其中的描述有任何疑惑,需要及时提出来,当场弄明白才可以正确的去完成这些功能。在后续的开发过程中,如果碰到任何疑惑,随时找BA或者QA了解清楚,不应该自己猜测着开发,更不可跟着心走。

Story kick off 的核心目的是确保DEV开发出的功能都是符合客户期望的。而Story本身存在错误并不在讨论范围之内。实际上在开发过程中,也未发生过这种情况,因为一旦客户的需求变更后,Story卡也会及时变更过来。Story kick off 可以follow以下实践:

  • DEV自己先完整地过一遍Story的描述。
  • DEV给BA和QA去讲这个Story的功能以及AC。
  • 要能够清晰的讲出来,并且三者达成一致,如果有疑惑,需要当场得到解决。
  • DEV开始开发Story,并自行将Story参照AC拆分成很多个子任务列表,然后逐一干掉它们。

最后一个实践严格上讲不是kick off环节里面的,它发生在kick off后,DEV自行决定怎么去完成功能。我比较推荐DEV在kick off后将Story划分成子任务列表,按照依赖关系和优先级排序,逐个干掉他们。一些敏捷管理工具(Trello, mingle, Pivotal Tracker, teambition)都支持这种任务拆分,你还可以很容易的记录与跟踪。

Story kick off也是一项短时间高收益的活动,因为在我们DEV界中,有一句邪门的定律:

猜出来的需求往往是不靠谱的,最终需要打回重做!

所以kick off能够有效的避免Dev自行臆测业务需求而产生的浪费。除此之外,能够弥补BA在编写Story的时候技术视角的一些遗漏

一些项目会引入好的开发实践,比如说BDD。它能按照人类自然语言去描述一个功能的实现。我们的Story描述通常会参照这种方式: as...when...then...when...then。这个时候,DEV、QA、BA可以在Story kick off的时候利用一些测试工具(Cucumber)一起来编写Story验收测试用例(主要由QA来编写),DEV负责编写代码来通过这些测试。理想情况下,验收测试用例如果正确完整,当所有测试都通过后,意味着Story功能已经完成。而且这种TDD的方式,代码出现bug的几率也会大幅度降低。

下面是一对Pair做Story kick off:


Pair

结对编程的开发速度通常小于简单地将一个人的开发速度乘以2,但它依然能创造价值:知识的共享,代码质量的提高,缺陷率的降低。

XP里面提到了结对编程,经过事实证明,它是一项利大于弊的实践。

通俗地讲,Pair就是两个人同时工作在同一个Story上,一起讨论Story的解决方案,并编写代码实现功能,一个人敲键盘,一个人看屏幕,穿插着进行。Pair的小伙伴在快速敲击键盘的时候会伴随一些交流,并时不时停下来讨论说笑片刻,亦或是在欣赏一下自己漂亮的代码。

两个人一起写代码即为Pair,那么如何进行高效的Pair呢,也有一些良好的实践:

  • 搭档的选择上,两个人的技能和经验最好是相当的,这样就不至于一个人成为被教育的对象,而另一个人成为键霸。
  • 有新人加入时,需要一个经验较丰富的老人Pair,最好是有良好Coach技能的老人,老人尽量只提供思路启发,并让新人多思考和动手实现。
  • 经验相当的Pair时,可以一起讨论解决方案,并达成一致,然后一个人写测试,另一个人编写代码通过测试,两人同时保持focus。
  • 定期更换Pair,粒度可以控制在以一个Story完成为节点。大一点的Story可以keep住一个人不动,另一个人进行更换。
  • 遇到技术阻碍时,分头并行寻找解决方案,并最终一起决定采取什么方案。
  • 当两个人对实现细节的优劣拿捏不定时,邀请团队经验丰富的老人做出建议参考。
  • 在一些很简单的defect上,可以不采用Pair。

Pair将本来可以并行工作的两个人聚焦在一件事情上,表面上是在降低生产力,实际上它确实是有一定的成本的。而这种付出并不会打水漂,最明显的好处是能够最大化知识的共享(尤其是更换pair的场景下),包括业务知识的共享、技术方案共享、解决问题思路的共享,这一点尤其体现在团队有新人融入的时候,通过Pair能够快速带领新人成长起来,提高整个团队的战斗力。另一方面可以提高代码质量,Pair实际上是两个人一直在不停的做Code Review,两个人的思维碰撞能够避免很多代码小聪明和不好的编码习惯。

有些时候,因为项目进度的紧张,Pair并不会这么理想的被落实,团队可以进行灵活的调整。如果Pair的时间减少了,可以通过加长Code Review的时间来做一些弥补。

下图是我跟TL Pair的剪影:


TDD

TDD,测试驱动开发,这项人人都称赞、却很少有人真的去做的活动,不应该只是一个被供奉起来的神。接地气,再接地气一点。

TDD,即测试驱动开发,强调的是测试先行。TDD是一个存在争议的主题,因为在一个连测试的没有的代码库中(多数客户也不关心测试代码,他们通常只想要看得到的功能),它的立身之本就不复存在了。我经历过只有纯手工黑盒测试的项目,没有单元测试、没有集成测试、没有E2E测试(测试金字塔, Martin Folower),所以TDD无从谈起。我也经历过客户要求测试覆盖率的项目,有专门的测试覆盖率工具(coveralls)来检测代码库,有的甚至集成在CI上作为一个硬性指标。

所以,TDD必须在一个有测试的项目中去讲。它跟我们先实现功能代码后添加测试的过程恰恰相反。我们根据对业务理解,先写一些测试(E2E,Integration, Unit),此时得到运行结果为红色(测试运行失败),然后编写业务代码让其变绿(测试运行成功)。

当然,TDD实践存在一定的门槛,TDD更多地考察一个人的设计能力,所以需要有一定经验的开发人员,而新人往往是很难做到这一点,但这不应该是新人不去尝试TDD的借口。

在实际项目中,可以根据团队自身的条件,灵活采取TDD去编码。就我个人的经验而言,TDD编码的时候刚一开始的时候并不是那么顺手(因为TDD更偏重设计),心里会觉得比较耗费时间,最终Story的完成时间相差无几,而TDD除了有效地降低缺陷率,还有以下三个方面的好处。

  • 从宏观把握Scope,开发人员不会在开发的过程中扩大或偏离Scope。举个例子,开始一个功能点时,一上来添加一个E2E测试,整个Scope在此时就被框定,然后再细分到内部实现,最终以通过这个测试来完成这个功能。
  • 提高代码的设计。当我们先写测试的时候,就会考虑到被测试的对象要尽可能被方便的测试,此时我们会尽可能的改良我的的API设计,以便利于测试,这样一来,我们写出的代码更具有可测试性,这样的代码往往具备较高的质量。
  • 确保功能不会被遗漏。我们一开始更多关注的是业务,而不是代码的实现细节,此时写出来的测试会更全面的涵盖不同的Case。

Code Review

不可否认的一个事实:人人都爱整洁的代码。而一个人单独编码难免会耍一些小聪明,或引入一些自身习惯难以察觉的不良代码。Code Review能让你提高警惕,并改善代码的质量。

Code review,检查代码,也叫代码审查,就是开发人员凑在一起来检阅彼此所产出的代码。看看有没有新的代码坏味道,看看有什么不合理的设计甚至是错误的设计,等等。

既然是开发人员凑在一起审查代码,那么Code Review会产生一定的时间成本(根据团队的规模1~2小时 = 5~10个开发人员),所以需要一些良好的实践来确保Code review的高效产出:

  • 团队一起拟定一个开始时间和时长,并落实到位,保证团队成员的参与度和Focus。
  • 短时间的描述自己的Story业务,主要Focus在代码上。
  • 持续跟踪记录,并获取反馈。这需要有一个人记录问题(可以按天轮流),结束后交给Owner执行更改,并且下一次Code Review的时候先过上一次的更改。
  • 必要的时候拉长时间,条件允许下建议在一个有大显示器的会议室中进行。

另外,从团队规模和时间安排上,可以遵循以下两个原则

  • 对于规模很小的团队,可以适当减少Code Review的时间和频率,如果团队经常Switch Pair,也可以适当减少Code Review的时间。
  • 安排在下班前进行。一方面,大家经过一天的高强度的思考与编码,适当停下来,看看其他人写的代码,同时将自己代码讲解出来,还能意外的获得一些灵感,或许能解决自己面临的阻碍(你所面临的问题可能已经被其他人解决了)。另一方面,如果这个时候发现代码的坏味道,需要改进的地方,下班后可以花少量时间作出更改。

长期的实践证明,Code Review能带来的好处有:

  • 让每一个人提高警惕:自己写的代码并不是只有自己看的,所以要督促自己做好。比如规避不想写测试,代码耍酷等。
  • 共同找出代码的坏味道(命名规范,代码整洁,API内聚性,面向对象设计),及时做出改正,提高代码库的质量,有助于后期扩展和维护。
  • 让团队成员知道他人在做什么以及怎么做,分享好的编码习惯和技术实现,有助于团队整体进步。

下面是某个时刻,我们Team四个人正在专注地讨论为一个函数取个更好的名字(猜猜谁是表情帝??):


Showcase

不管客户有多忙,也要定期让客户确认自己的期望是否得到满足。在签订合同前,要跟客户达成一致:Showcase的地位不可动摇。

Showcase就是给客户演示我们上一个迭代已经完成的功能,它的宗旨是及时得到客户的反馈,确认团队的产出是否满足客户的期望,降低需求变更返工的风险。

Showcase从项目开始时周期性地进行,并直到项目交付。这个时间间隔是基于团队设定的迭代周期,我们团队是两周一次。团队跟客户安排一个远程会议(如果是在客户现场,一些参与讨论效果更好),主要涵盖了以下内容:

  • 跟客户确认上一个迭代的Story列表。
  • 项目目前的交付状态。是否正常进度,会不会延期。
  • 演示上一个迭代完成功能。在线系统演示,需要一个staging环境。
  • 客户对功能确认,对达到期望的story签字,反之。我们记录下问题,并修改,再次确认签字。

Showcase的目标是客户,需要针对不同的客户有不同的策略。如若客户觉得每两周一次过于频繁,团队可以变通调整迭代周期,通常建议的是1~4周,不宜太长,太短也没什么效果,至于如何权衡这个时间,有两点可以参考:

  • 在探索中找到适合团队的迭代周期,如果发现每个迭代时间不够用,要么是story划分太大,要么是迭代周期太短,这时需要根据几次的平均结果做出调整,适当扩大迭代周期,或者更合理的拆分Story。
  • 如果Showcase的时候功能背离了客户的期望,通常是因为迭代周期太长。因为用户的需求以及团队对需求的理解都在随着时间的推移而变化,导致发布时的产出并不是客户需要的。这个时候,可以考虑适当缩短迭代周期,让反馈来的更快更舒缓一些,而不是更慢更猛烈。

试想一下传统瀑布开发模式下,一个功能的演示通常安排在在某个里程碑节点,此时项目或许开展了半年或一年甚至更久,客户这个时候见到自己的系统,简直会惊叫起来,原来这压根不是他们想要的东西(因为客户一开始都不知道自己要什么),即便开发团队严格按照预先的设计文档。这是一种时常发生的灾难,它导致大量的浪费,且很难挽救。

敏捷开发可以规避这种灾难性事件的发生。而Showcase在敏捷开发中是一个不容忽视的环节,它契合了敏捷宣言中的拥抱变化优于遵循计划。Showcase能够让团队在每个迭代完成后及时从客户那得到反馈,对变化做出快速的响应,避免了劳动成果的浪费以及方向的偏离,也能最大化让客户的期望得到满足。

为了达到更好的Presentation效果,Showcase通常提前准备一个总结性的Slide来引导整个过程的推进,结束后该Slide即为产出的一部分,另外也会有一封总结性的邮件来跟踪记录Showcase的结果。


CI

没有CI的项目开发是在耍流氓。CI在Agile中是一项最基础的设施,它通过自动化来提供有效的反馈机制以及高效的部署,大大降低代了码集成和项目交付的风险。

CI,持续集成。在敏捷开发中,它是一个项目开始前必须搭建起来的基础设施。当代的软件开发项目中,几乎没有项目是只有一个人在开发的。超过一个人就形成了团队,每个人同时并行开发不同模块的功能,这就涉及到代码的集成,所以代码集成是几乎所有开发团队都要面临的问题(一个人的开发项目不在本文范畴中)。

持续集成跟团队开发人员独立开发没有冲突,相反,借助一些工具(Jenkins, GoCD(ThougthWorks开发), Travis CI),它能快速的对我们开发人员提交到代码库的代码作出反馈。开发人员每天都在代码库提交代码,版本控制工具(比如Git)在提交前必须更新代码库最新的代码(解决冲突,代码合并,应用更改),然后将代码提交到代码库中。这个过程是代码集成的第一步,最重要的是如何确保这些集成是可靠的,以下是一些关于CI的良好实践:

  • 开发人员对自己编写的代码添加足够的测试覆盖率。这是基本,基本最无敌:一来验证代码的正确性,二来防止被误更改。
  • 每个人提交代码到代码库之前在自己的机器上保证单元测试都能通过,很耗时集成测试和E2E测试可以更多的交给CI去跑。
  • 借助一些CI工具(见上文),将代码集成的结果反馈展示在团队所有人都能看到的Dashboard上,一定要大家都可以看到。
  • CI定期检查代码库的更新,只要有更新,就要运行所有的测试。这里有个权衡:不耗时的单元测试每次全部运行,集成测试也要频繁的运行,耗时的E2E测试可以稍微执行少一点(比如设置夜间执行)。我们这个项目,是每次检查到更新就会运行所有的测试(单元测试+集成测试6分钟,E2E测试30分钟)
  • CI如果没有通过,所有人都应该停止向代码库中提交代码,直到CI被修复,所以如果CI挂了,能够及时通知相关开发人员,要第一时间修复。
  • 所有测试通过之后,CI负责自动化部署到不同的环境(Test,开发团队测试环境;Staging,客户ShowCase环境;UAT和Production,用户验收测试环境和生产环境,通常开发团队没有权限),并正常启动所有的服务。

通过这些实践,CI能带来的价值也是相当可观的,主要体现在五个方面:

  • 减少重复的过程。CI通过自动化,将一些需要重复执行的操作(代码审查、编译、测试、构建、部署)自动化管理起来,大大减少了重复的过程,节省了大量的时间。
  • 降低风险。开发过程中,每天进行多次集成,并且添加了足够相应的测试,每次集成CI都会快速检查代码中的缺陷并提供及时的反馈,降低了未知的风险。
  • 可视化。CI提供了大量真实且最新的数据,能够让我们关注当前集成的趋势(例如构建时间、构建失败比例、测试覆盖率等),有利于有效决策。
  • 增强团队的信心。每次构建的结果都是公开透明的,所有人清楚地知道自己的每次提交改动对软件所造成的影响。
  • 随时随地可以生成可部署的软件(CD)。对于客户来说,可以部署的软件产品是最实际的资产,而CI让我们可以在任何时间发布可以部署的软件。

可以借助一些工具,比如Chrome插件BuildReactor可以将CI的多个Pipeline集中展示出来。

下面是我们CI的Dashboard,使用了一个Chrome插件BuildReactor(如果加载不了就说明需要翻墙)将Go的多个Pipeline集中展示出来。


Retro

团队专注于交付目标,埋头干活的同时,也要懂得停下来总结过去,并更好地抬头看路。

Retro是Retrospective的简写,即回顾。团队通常以回顾会议的形式进行,大家坐在一起,对过去的这段时间里,我们Team的工作状态(团队合作,技术实践,团队氛围等)做一个总结,它有一点基本思想:对事不对人,大家思想自由Open。如何做到这一点,下面是我们Team的实践:

  • 确认构建安全的环境。什么意思呢?就是每个人都是觉得当前的会议是可以自由发表意见的,而不是因为某些人(比如说不友善的Leader)而不敢发表意见。开始前每个人对安全系数打分,1~10分,如果平均分数偏低(比如低于6分),需要将Leader从会议中"驱赶出去",直到大家觉得安全了才好。
  • 建立几项总结指标(Well, Less Well,Suggestion,Action),大家分别对前三项提出自己的看法。第四项是综合所有前三项的结果总结出来后面要做的事情。
  • 使用Sticker纸片,最好是用马克笔写(这样一张Sticker就不能泛泛无边的写),一张Sticke写上一个点的内容即可。
  • 编写Sticker内容的时间控制在5分钟以内,每个人自己将Sticker按照分栏贴好,然后Facilitator(通常是PM或BA)开始带着大家过每一栏的Sticker,对Less Well栏中,将同一类的问题归纳起来,总结出相应的解决措施。
  • 将Action栏中的Sticker指派Owner,并落实。
  • 如果跟客户关系融洽且相对容易参与进来,可以将客户Involve进来,然后一起构建一个安全的环境(有可能因为大家的打分较低,客户不得不“出场”,所以客户参与不是必须的)。

说得天花乱坠,没有行动,犹如竹篮打水。Retro这个环节最核心的产出物是Action,团队共同一致商量出来的措施,有没有效果就在于行动了,所以Action分配了Owner之后,一定要跟踪这些Action有没有落实执行。一方面,需要Owner拥有高度的责任心和执行力,尽职将这些Action落实执行。

Retro的细节因团队而有些差异,而它的理念是一致的:总结过去,做的好的方面继续保持及加强,做的欠佳的方面一起讨论改进措施,并尽全力落实。Retro让团队在实践中摸索出适合团队的最佳实践,引导团队和个人不断自我完善,追求卓越。

我们Team的一次Retro


总结

这是我参加的一个关于敏捷实践很完善的项目,个人亲身经历了这些,深深体会到这些敏捷实践带来的益处以及个人的成长是非常大的。敏捷很好,但不只在于这些流程形式,在形式背后,我们应该深入思考这些实践是否真的让团队变得高效?让交付变得更加顺利?每个团队都是不同的,不必拘泥于这些流程形式,而是要追求这些流程产生的真正价值与意义。

PS:文章中提供的链接在有网络的情况下如果不能访问,确认自己是否可以翻墙,如不可以,切勿较真。


术语注释

  • PM:Project Manager,项目经理
  • BA:Business Analyst,业务分析师
  • TL:Technical Leader,技术领导
  • QA:Quality Assurance,测试人员
  • DEV:Developer,开发人员
  • UX:User Experience,用户体检设计师
  • AC:Acceptance Criteria,验收条件
  • UAT:User Acceptance Test,用户验收测试
  • Retro:Retrospective,回顾会议
  • TB: Team building,团队建设

Posted by 袁慎建@ThoughtWorks

版权声明:自由转载•非商用•非衍生•保持署名 | Creative Commons BY-NC-ND 4.0

原文链接:http://sjyuan.cc/first-impressive-agile-experience-in-thoughtworks/

以上是关于我在ThoughtWorks中的敏捷实践的主要内容,如果未能解决你的问题,请参考以下文章

TiD系列线上沙龙 | 探索式测试在敏捷开发中的落地实践

微服务敏捷开发模式探索与实践

中国敏捷开发和中国程序员的爱恨情仇

敏捷管理系列-学习实践Scrum,看这一篇就够了!

敏捷软件开发

深入核心的敏捷开发