Day 29 「Try it!」单元测试与软件工程

国内饮料大厂有句广告标语:「Try It!」笔者还蛮喜欢的。


图片截自网路

从小在父母的保护下长大,一直到自己出国,到人生地不熟的地方读书,真正遭遇的挫折了,这才发现,以前父母帮我做的事、舖的路,虽然很好很完整,但也不小心使我少了自己探索学习的机会。

这样的体悟,後来对我的影响很大。往後我再也不相信世上有「最佳解」这件事。我要求我自己与我的团队,工作上遇到什麽问题,不能坐着等老板或主管来告诉我他们希望我们做什麽。工作上有问题,困扰的是我们,首先应该要是我们自己去找解法,而找到解法後也没有人能确定解法好不好,只能去「试看看」,自己感受一下。

说不定到最後我们能发展出一套模式,可以更广泛地应用在每天从事的软件开发上,那就会成为我们专属的,自成一格的「软件工程」模式了。

还记得我们在一开始时有聊到单元测式与敏捷开发的关系吗?今天要来更深入探讨这件事情。或者更精准地说,我们要聊的是「软件工程」。

导入 Extreme Programming

笔者蛮喜欢 Extreme Programming 这本书的。作者 Kent Beck 在书中提出了许多他建议的软件工程实践,而我认为书名「Extreme」这个字真的下得很好,因为你在工作上不断精进各种软硬实力,不断改善所有你可以改善的事情,认真把「Programming」这件事做到极致,其实也就差不多是书中形容的那样了。有人将这些实践分门别类,画成下图的样子:


图片截自:12 Core Practices In Extreme Programming XP

在上图中,最内层黄色的是「工程实践」,中间橘色的是「团队协作」,最外层的是「流程改善」。

TDD 被放在这图中的最内层,旁边摆着的是重构、简单设计,与结对编程。这代表什麽意思?就是你第一步要先把内层的四件事做好了,你做外圈才会顺畅,才有意思。

那你连 Unit Test 都没有,你跟人家一来就要搞 Scrum,玩「估算点数」,搞「持续部署」,是在忙什麽?

有人野心很大,请了一个「名师」来讲了一个三天的 session,有人阮囊羞涩,买了一本书大家分着读完,无论如何,总之结束後他们就开始「导入 XP」的所有实践,期待能一战成名,自此平步青云,一帆风顺。

可想而知,都是挂掉比较多。

如果这些人真的有把书读懂,他们肯定在书中有读到作者本人的建议:「你不太可能一口气同时开始所有实践,那会扼杀一个团队的所有精力。」是的,Kent Beck 建议我们先分析现在团队遇到最棘手的问题,然後一个一个实践慢慢引入。」

所以,不要「导入」XP,要在适当的时机,拿来解决工作上的瓶颈。

导入 Scrum

有道是 Scrum 三本柱:探索、调适、透明化。笔者曾经参加过 LeSS 名师吕毅的培训课程,对其中的一个「野雁南飞」的故事印象深刻。

在北美,冬天是非常冷的,因此,当地的野雁在靠近冬天时,会聚在一起商讨对策,决定一个良辰吉日,找一块地灵人杰的好地方,由资深的野雁当 Leader,数到三就一起往目的地飞去。飞的时候还不忘排好队,由 Leader 决定今天是要飞「人字型」还是「一字型」。


图片截自 kknews

你不是真的相信,对吧?

以上当然是我瞎掰的。真正的野雁,在出发前并不会知道这次旅行的目的地在哪,牠们也没有所谓的「Leader」来决定事情。好,牠们是会有一个 Leader,不过不是拿来决定事情的,只是飞在最前头,好让其他同伴对齐而已。

那麽,野雁怎麽知道要飞去哪儿过冬呢?如前所述,牠们不知道。虽然不知道,但牠们还是有个「共同目标」:要找到「温暖、有食物,且安全的地方」。

於是,有了共同目标後,牠们就先讨论一下,但现在对於冬天的了解还太少,只知道往南应该比较温暖,於是就先往南飞一段试试。

飞一小段後,停下来休息一下,并同时观察四周,看看是否有比较温暖、有没有足够的食物,附近天敌多不多。好像有比较好,但还差一点,於是调整一下方向,再重新上路,寻找下一个地点。

再飞一小段後,再停下来休息一下,并同时观察四周,看看是否更温暖、食物更多,附近天敌更少了,然後,重复以上步骤,直到找到一个栖息地,气候、食物、安全性都满足了大家的需求,就停下来过冬,等待春天的到来。

以上,就是笔者在吕毅老师的 CSM 课堂上,听过的北美野雁南迁过冬的故事。

「你到底在讲什麽啊?」

阿弥陀佛,这位施主,我在讲 Scrum 啊!这不是野雁的故事,是 Scrum 的故事啊!


图片截自电影 - 达摩

跟 XP 一样,很多人都是用自己的方法学习了以後(或是不学习,直接只看标题),就想要来工作场合「导入 Scrum」,期待能一口气解决工作上所有问题,变成一间「很敏捷」的公司。

可惜的是,这种也是挂掉比较多。

如果大家有真的把 Scrum 搞懂,应该会知道,Scrum 每个 Sprint 结束後,要得到的是「Potentially Shippable」的功能。什麽是「Potentially Shippable」?这我们先前聊过了,就是要「几乎可以上线」,也就是要通过测试。随着产品长大,这个测试的涵盖范围就会越来越大。这时如果你只仰赖 QA 的人工测试,只是帮 QA 不断加工作而已,对 Scrum 的「探索」与「调适」一点帮助都没有,甚至 QA 就只测部份功能了,这也伤害了产品品质的「透明度」。总之没有自动化单元测试的 Scrum,对 QA 与或老板来说,还不如你一口气做完,QA 一口气测完,老板一口气拿出去卖来得方便。

所以,不要「导入」Scrum,要在适当的时机,拿来解决工作上的瓶颈。

导入 CI/CD 与 DevOps

笔者出社会的第一份工作,是在一间德商的台湾办公室,从事 Ruby 的开发。那时的部署政策,是「严禁在产线下部署指令」的。他们规定每个 RD 都要在自己电脑上装 VM,装跟产线一样的 OS 与 DB,从环境安装、资料库建置、程序码下载、资料表的创建,全部都要用 shell script 脚本执行,而且脚本一定要版控,所以从 RD、预产线环境,一路到产线,所有的部署、退版、重新安装、资料表调整,全部都要以「执行受版控脚本」的方式来进行,而且「每个人都要用同一套脚本」。

在那个 Git、Docker 还没红到台湾来,k8s 也还没问世的年代,我个人认为那间公司能做成这样,算是很厉害了。

後来进到台中一间当时还蛮大间的电商,因缘际会下认识了Ansible,自此疯狂爱上这位新朋友,它几乎能做到以前写 shell script 能做到的所有事情,除了一样可以版控,在多环境多机器的控制上,比以前的 shell script 方便很多。使用了 Ansible 以後,每当要联合更版时,我们总是 5 分钟搞定,而隔壁 Team 还在那边忙着包版、写文件、手动测试、退版修 bug。那感觉还真不错,不为什麽,就是我一直就很懒得做这麽匆忙又赶的事情。

後来又认识了自动化界有名的 Jenkins 大叔,我发现他除了主动触发,还可以排程与 Hook 触发我需要的自动测试、打包、以及指定环境的部署,这时再加上原有的 Ansible 来与 Jenkins 一搭一唱,简直惺惺相惜情不自禁!


图片截自网路

当然後来还有一些跟 Docker、ELK、k8s、GCP、Slack 机器人…等邂逅的浪漫故事,碍於篇幅就先省略了。

後来才知道,这些就是人家说的 DevOps 的其中一部分啊(虽然只有一小部分)!但知道这个名词时已经是很久以後的事了。我只知道遇到问题我就想找方法解决,至於他潮不潮,上不上太空,我倒无所谓,我只要能「优雅一点地」解决我手上杀猪公的问题就好。

其实笔者是一个很懒的人。已经有好几年,我与我的团队,在「push」完程序後,後面的事都不用做了,几分钟後讯息自然会发到大家手机上,有问题到时候就知道了。我们决定把那些重复枯燥的事丢给机器做,是为了省下时间做机器做不到的事:设计与重构。你说,没有足够的单元测试,谁敢「放手」成这样?

所以,不要「导入」CI/CD 与 DevOps,要在适当的时机,拿来解决工作上的瓶颈。

导入 User Stroy

曾经,笔者也是会写出「As a 用户,I Want a 注册功能,so that I can 注册」这种为赋新词强说愁的 User Story 的人。直到有一天,RD 在回顾会议上,抱怨我的 User Story 他们看不懂,这时我才发现 User Story 不该是一种文件,而应该是一种「媒介」。

什麽意思?

如果我现在跟各位读者说:「把不起妹妹就巴头」,各位应该只想到那个搞笑短片,但是如果跑去跟我们团队讲,大家都会告诉你,那是我们系统一个功能的代号。这是因为这句话曾经在团队内引起很热烈的讨论,而且我们为此想了一个很特别的 Solution。因此「把不起妹妹就巴头」就成了我们团队回想起这个系统功能的沟通「媒介」。

User Story 也该如此。说到底,当初大家究竟是为了什麽才要开始写 User Story 的?十有八九是为了传统的 Spec 读起来没有共鸣,不容易理解吧?既然如此,那换成 User Story 後,如果还是照本宣科,拿着 Solution 来回推「使用者」的故事,那这个故事根本不会有共鸣,根本无法帮助理解,还不如不写。

「现在的网页,注册要填十项资料,像智障一样,用户非常不爽!」

这种 User Story 是否读起来比较能有共鸣呢?笔者隔着萤幕都能感受到用户的怒气呢!这下修改起来,方向就清楚多了吧!

这跟单元测试有什麽关系?

有啊!User Story 写得好,场景清楚,测项自然就好列,功能自然就不容易做错啊!而且不只单元测试,能设身处地为使用者着想的 RD,开发出来的程序是会难用到哪去,你说是吧?

所以,不要「导入」User Story,要在适当的时机,拿来解决工作上的瓶颈。

不要再「导入」了

在写这篇时,其实笔者心情是复杂的。明明 Scrum 是这麽好的东西,却被一些不明究理的人瞎弄,害大家误会 Scrum 以为它没用。以上的 Scrum 可代入近年流行过的其他 Buzz Words。

有人曾经问我怎麽「导入」单元测试,怎麽说服老板给我时间写测试、写 Ansible 设定、将产线服务容器化的,我实在是觉得这些问题很难回答。但後来想一想,又好像很好回答:「我从来没有跟老板多要过时间啊!」

单元测试、重构、自动化部署、容器化,这些东西不就是设计来帮大家节省时间、降低出错率的吗?如果需要「更多时间」来做这些事情,不就本末倒置了吗?

所以,我建议大家不要想着「导入」什麽酷东西,而是要多观察、感受,看看你工作上实际遭遇到什麽问题?哪个是你目前最大的瓶颈?你手上有什麽资源可以运用?不懂的,你要花多久才能学到可以拿来试用?

这就是「模式」啊!在一个场景下,使用一个方法,解决你想解决的问题,而不是拿着路上听到的方法就拿来乱套,因为那个方法不一定适合拿来解决你的问题啊!平底锅很好用,拿来炸薯条也不是不行,但就是有那麽一点不方便,用起来卡卡的,效率也不高,反而要花更多时间处理善後,不是吗?

你觉得薯条炸得太慢吗?那就先回头看看,你现在拿来炸薯条的,是什麽锅吧!

「该做什麽就去做,有问题就修正。」是笔者对於软件工程的实践,一贯采取的态度,我也建议各位大胆地去试试。反正现在你都抱怨成这样了,再差也不会比现在差,对吧!

谜之声:「不做不会怎样,做了很不一样!」

Reference

  1. [Scrum根本没用] — 从 XP 看 Scrum:https://tinyurl.com/6z98kb6y
  2. 12 Core Practices In Extreme Programming XP:https://www.c-sharpcorner.com/article/12-core-practices-in-xp/
tags: ithelp2021

<<:  Day 15:101. Symmetric Tree

>>:  最短路径问题 (3)

Day21:21 - 结帐服务(5) - 後端 - 结帐 X PayPal Python Checkout SDK

Salom,我是Charlie! 在Day20的时候我们完成了createOrder跟Capture...

新手要如何开始做B2C电商? 如何在开店平台架设品牌官网?

我认为想要做电商的新手,必须要掌握以下几点: 1. 确定产品和货源 成立电商第一步就是要确认自己所要...

Day27 - Linux 提权(1)

最小权限原则 principle of least privilege 指的是使用的帐号应该要跟服务...

Day 11-假物件 (Fake) - 虚设常式 (Stub)-3 (核心技术-3)

看程序码说故事-3 在昨天 Day-10 把 EmailSystem 从 JJEmail 这只套件抽...

DAY30-结语

终於!!!最後一天啦!!!今天什麽范例都不会讲哈哈哈!!!我想讲一下我做完这三十天的感想!!! 我觉...