前言
Kent Beck,XP极限编程以及TDD测试驱动开发创始人,同Eric Gamma一起发明了JUnit,敏捷宣言17位起草人之首(姓名字母排序)。
厌倦了出名之后,生活如同放在显微镜下事无巨细都被放大,于是放羊了十余年(是真的养羊去了),11年重出江湖被请到Facebook,工作7年后离开,继续放羊的生活。
9月6号我司邀请Kent做了一场内部研讨以及主题演讲,有幸全程参与,获益良多,也有颠覆原先想法的,也有印证最近思路的,整理总结如下供学习和讨论。
NOTE:
以下内容部分来自当时Kent的语录,结合我个人的心得体会,所以以偏概全,理解有偏差兴许也是有的;
体会思想重于纠缠细节,大师也说Depends,我也不想去总结面面俱到的文章;
有些观点会有争议,比如说关于测试,关于代码评审,内部也有讨论,有人说太过理想化,但总体思路上我是认同的,梦想总还是要有的;
Kent的话是有上下文的,Facebook的实践也并非放之四海而皆准,要视不同的企业和团队,酌情进行采纳;
关于度量
度量的原因是缺乏彼此的互信
讨论软件研发效率的话题,本身就是一种缺乏互信,我们不是一个工厂,无法按件计量软件开发效率。
如何建立互信,最好的方式就是透明化,一起协作,以小的循环的方式来工作。
指标能够帮助学习和了解,但不要让指标变成目标。
指标不是拿来做相互的比较,指标是对自己的反馈。不同的业务,不同的团队,指标是不一样的。没有放之四海而皆准的度量指标。不要晾晒指标,或与绩效挂钩,你度量什么,你就得到什么。即使是像部署频率这样广泛应用的指标,一旦进行考核,也一定会变了味儿。
度量是设计和实现的参考,是为了自我改进,自己和自己比,只看趋势,不应该有绝对值的目标。拿两个团队的成熟度或框架度量指标相比没有任何意义。Facebook没有要求统一的Code Metrics要求。
关于代码评审
有Code Review 比没有Code Review好,但是没有Code Review比有Code Review好
很绕的一句话,需要仔细思量。代码评审会造成延迟,以及工作切换,但总比没有好,虽然效果有限。
更好的是通过协作的方式来保障质量,比如结对编程,此时,code review的作用就没有那么明显。
所以代码评审不是目的,质量才是。
也有人说,Code Review的重要性在于社会性意义,当你知道有人会检查你的代码时,你会更认真。
对此,我表示认同。但是需要注意,当知道有人会检查你的代码,可能产生两种心态,一种是更具责任心,一种是产生依赖心理。
测试人员于开发质量也是如此,知道有专职的测试时,自己少做一个测试,也总会有人在后面把关。
Facebook所有代码在公司内公开,由不同的人维护,每个人都有修改权限,可以push到不同的代码主干和分支上,并可以部署到生产环境。一个修改,几亿人会使用,成就感极大,压力感更大,由此转化成责任心。
开发人员全权负责,没有测试会帮你检查,没有其他人可以依赖,权力越大责任越大,最终的结果却很好。因为这种自由信任的氛围,因为鼓励尝试,鼓励失败的文化。
关于代码风格,工程师应该把精力投入到软件设计和实现这些重要的事情上,不应该过多的关注编程风格的事情,这些可以使用工具来帮助,这类的小错让机器来解决,让程序员来犯更大的错误。
关于规则
原则比规则重要
认为遵循规则就能够成功的,就像货物崇拜(关于货物崇拜,请搜索何勉和王明兰的文章)。
遵循规则背后,是什么心理?期望安全,但事实上是缺乏安全的心理;遵循规则最后失败了,可以推卸责任,可以向领导交代。
在安全的氛围下,人们才会彰显个性,会乐于暴露问题;缺乏安全的环境,人们会驱同,从众。我们要思考,要动脑筋。当我们都喜欢跟随规则时,组织的症状就已经比较严重了,因为这是大家怕担责。我们要质问组织为什么形成了跟着规则走,就更安全的文化。为什么不鼓励追求一个更大的目标。
目标一致胜于遵循规则
要了解背后的purpose,目的与目标,而不是盯着眼前的事情,遵从某种规则。
是为遵守规则而工作,还是为了实现目标而工作。从组织和文化看,当发现我们组织中所有人都跟着规则走,而不是朝着组织的目标去努力做得更好,就要认真考虑,这种文化到底是怎么形成的
Agile是什么?如果你能够高效的达成你的目标,你就是敏捷的,或者说,你不用在意自己是否是敏捷的,不必介意与纠缠敏捷的定义,黑猫白猫,抓住耗子就是好猫。遵循流动原则,小的,频繁的质量交付,is better。
关于测试
Facebook自动化测试很少,TDD做的不多,代码测试覆盖率不高。Kent刚加入的时候,开了一次TDD课程,边上的Excel高级使用指导,人员爆满,边上的拉丁舞课堂,人头攒动,而TDD的报名人数为0。
他很挫败,觉得这样做是有问题的,但随后逐渐接受,因为测试的目的是反馈发现缺陷,而发现缺陷的方式,不仅仅只有测试。
质量不是测试出来的,测试只是一种反馈机制。
认为测试可以保证质量的,只是自欺欺人。
开发,代码审查,构建,部署,测试,发布,上线,每一个环节都是反馈。既然这些质量反馈有效,为什么一定要测试才能保证质量?如果可以通过更经济有效的手段获取反馈,(某些)测试是可以省略的。
要重视测试,但又不能矫枉过正,不要过度迷信和依赖。
对测试进行分级,根据重要性,出错概率,出错成本、影响程度、恢复速度等,进行判断;多高的概率会犯错,出错的成本多高,恢复有多快,来决定测试,或者说验证和反馈,放在哪个环节,哪些原先固有的测试可以拿掉。
这与测试前移的理念有所出入,但我认为两者都合理,要辩证的来看。从经济的角度来综合判断:减少部分测试所节约的时间和金钱,由此可能引发的潜在风险以及后果,快速交付所获取的价值收益,快速获取反馈避免闭门造车而减少的投入成本。
缺失的测试,对于质量而言,也许会是一种债务,但如果和快速上线相比,价值大于风险,就可以做出经济的选择。
此外,上线前做的测试,如果是基于主观臆断,还不如上线后获得第一手的客户反馈来的真实可靠。
Feature flag, put code behind, don’t need test。通过功能开关,出错后关闭功能,降低影响,那么有些测试也许就变得不那么重要。
以上判决根据不同的系统和应用而不同,对于比如内核,保密这类的设计,测试还是很重要不可或缺的。
是否需要专职测试人员,与代码的反馈周期有关。
25年前,我们都说不要相信开发人员会做测试,但是现在开发人员要为自己的开发结果负责。
这里的关键在于反馈周期,编码好几个月,测试几个月,开发和测试分离是可以的,但编码10分钟,马上测试,怎么可能换人?切换与等待是有成本的,时效也是问题,开发交付测试,过了几周,测试结果反馈回来,开发已经不知道这个功能的上下文了。
不断缩短的反馈周期,要求开发对自己的代码质量负责。
从这点上来看,与测试前移的理念是不谋而合的,开发对质量负责,但同时又对测试的投入有一个平衡。
关于质量
代码质量最重要的特征是你能否基于它进行试验,试验的成本有多高,这是一个定性的问题,而不是定量的问题。
Good decision comes from experience, experience comes from bad decisions
经验来自于犯错,如何快速的从错误中获得反馈,并快速调整。
我们可以找有经验的人来,避免犯错,但这种人很少;我们也可以找没有经验的人,通过鼓励他们在工作中不断尝试,不断犯错,缩短反馈周期,降低犯错的成本,来增长经验,避免犯更大的错误。
第二种方式更经济适用,遵从成长型思维。有经验却无法成长的人,知识结构用不了几年就过时了。创造并鼓励实验和学习,对于企业来说更持久收益。
成功也好,失败也好,都是经验积累的过程,没有人天生就是成功者。
我们要用没有经验的工程师来开发出好的软件,那没有答案;如果说我们要把没有经验的工程师变得有经验,那么有很多好的答案;如果说,没有经验的工程师,又没有时间学习,那谁也没有办法。
软件的本质是变更,我们的软件设计如何为了更容易的适应未来的变化,因此,我们就要想办法通过降低每次变更修改的模块,修改的文件数量,来降低变更的风险和成本,终极办法还是解耦。
应该培养工程师对代码坏味道保持敏锐嗅觉的能力,让他们能够发现问题代码,然后要教会工程师掌握代码重构的能力,持续对坏味道代码进行重构。
关于TDD
当遇到TDD的问题,从来都不是TDD的问题
是设计的问题,是测试的目标太大。
TDD是工程师治愈焦虑的一种方式,分解问题,试验并获得反馈的一种方式。
测试是一个学习的方式和过程,反馈的一种机制;TDD是一个非常漂亮的短循环, TDD也是一种教育的方式;
TDD可以帮助新人快速通过试错取得成长,是一个开发人员积累经验的过程,当获得经验后,TDD要不要强制做其实并不重要,视每个人的风格以及习惯而定。
测试的组成包括,准备,执行,评估;如果准备的时间太长,则测试失去了意义,这样的情况不适用于TDD,就像数据库测试,需要前期花费大量时间准备数据;如果评估的时间过长,同样也有问题,UI测试就是这样,需要不断重新评估测试用例是否依然有效,因为界面经常变化;
关于互信
Facebook是怎么建立互信文化的?
核心是你想让工程师工作变得简单,还是想让管理者的工作变得简单
管理简单很容易,下命令就行了,但事实上不奏效。让工程师工作变得简单,就要管理更深入,更透明。
自上而下强压工作量,毫无意义,这是缺乏互信的体现。核心是要建立互信机制,建立互信的机制唯一方式,是管理者要深入团队,一起协作,透明、小步快跑、快速反馈。
从来都是信任的问题,而不是项目管理的问题
这是一个信任问题,不可能通过项目管理的手段来解决一个信任问题。
TIME SCOPE COST QUALITY,你只能承诺其中的三个,不可能全部承诺;
COST增加,可以加人,也可以降低质量,通常最终都不会奏效,而最终还是要从范围上做文章,控制SCOPE或者增加时间是有效的;
所以一开始就按阶段交付,及时获取客户反馈并沟通调整范围和计划;
锁定所有的内容,只能最后向客户跪拜道歉,就像Kent现场的表演。