一、前言
软件交付过程是用代码实现各用户关注点的过程,也是架构真正经受第一轮实战考验的过程。软件交付的结果可以检验架构是否真正地如之前所设计的那样能满足各方面用户的关注点。所以软件交付过程是否理想很大程度决定了架构设计的落地是否理想,也决定了系统满足各用户关注点的效果是否理想,那什么才是理想的软件交付过程呢?
二、从国内IT行业加班多说起
国内IT行业历来都是加班多的代名词,那为什么国内IT行业加班这么多呢?先通过笔者身边的一个真实的故事来说起:
笔者的朋友小N在国内一家大的公司工作,这一年来他加班都特别多,每天平均在晚上十一点多才能下班,有时候还需要连续搞几个通宵,人看起来非常疲惫。跟他聊了以后,了解了导致他加班的几个主要原因(问题有点多,但确实是如此):
原因1:上个上线的版本用户在使用过程中存在比较多的问题,需要进行紧急的支撑和补丁升级。
原因2:很多时候上面的领导需要给更上一级的领导演示,需要在版本的开发工作外额外再开发一个演示的版本。据他预计可能50%左右的版本外的工作都是给领导做演示版本。
原因3:公司层面要求内部所有的系统云化,所以一段时间都在搞现有系统的微服务化以及对于DevOps的支持。领导对这个完成的时间点又卡的很紧,认为只是把之前的功能微服务化而已,又不需要做业务的变更,导致那段时间加班巨多。
原因4:虽然在生产环境和测试的测试环境中搞了部署的自动化,但是很多开发人员还是使用很少量的环境进行功能的验证和问题单的回归验证,在过程中可能会发生文件替换冲突等问题,导致大量的时间花费在部署问题的定位上。
原因5:有的领导要求每周一个小版本,每一个月一个大版本,但是软件交付过程中的自动化程度又不足以支撑这样一个目标,导致测试每次基本上都要去做全量测试,测试加班也非常严重。
原因6:现有系统使用的技术都比较老旧,基本上还停留在六七年前的时代,特别是对于前台界面还是jsp+div+css+jquery的技术栈,导致前台代码越来越臃肿,加之对前台代码的重视程度不够,代码越来越腐烂,功能的增加和修改都极其痛苦。
......
我相信上面的问题在国内很多的公司都存在,这可能也是国内目前很多公司IT人员加班多的原因的一部分。下图是高德公司2016年发布的年度加班多的公司TOP10:
上面这些问题都是软件交付过程中出现的问题,那软件交付过程应该怎么做才是比较理想的呢?要回答这个问题,我们先来看一下软件交付过程包括哪些步骤。
三、软件的交付过程包括哪些步骤?
下面是笔者认为的软件交付过程所涵盖的步骤:
下面就对各个步骤做一个简单的描述:
(1)版本开发:这个过程主要是开发人员把代码编写完,并把自验后的代码提交到代码库中。
(2)版本构建:当代码都提交完后,需要进行版本的构建,目的是要构建出版本的软件安装包,当然也包括执行一些代码质量检查、自动化测试等。
(3)版本部署:当版本安装包构建完后,就可以在测试环境进行版本的部署。
(4)版本测试:部署完后,就可以进行进一步的自动化测试,也就是系统集成测试。测试人员可以选择几个关键功能进行人工测试覆盖。
(5)版本发布:当测试没有问题,就可以把版本发布出去,发布出去的版本就可以部署到生产环境了。
四、软件交付过程中加班多的问题分析
从分析的结果来看,软件交付过程加班多主要是以下三大原因:
(1)软件交付过程中自动化程度不够,人工参与过多,导致交付效率不高。
(2)软件交付过程中领导的干涉太多,安排额外的工作以及不切实际的规定完成时间点。
(3)使用的技术已经不适用,导致可扩展性和可维护性难,开发效率低。
第二个问题是领导的管理方式问题,第三个问题是技术选型的问题,在本文中不做展开。
下面主要针对第一个问题阐述以下笔者认为的理想的软件交付过程到底是什么样子的。
五、传统的软件交付过程
为了说明怎么解决第一个问题,下面让我们总结一下目前软件交付过程中的传统做法(按照敏捷中的概念进行说明):
(1)开发人员接到story开发任务后,进行story的分析和设计,并和测试人员一起沟通澄清该story的具体细节,包括story的范围、规格等。
(2)澄清完后,开发人员进入编码阶段,测试人员进行story的测试用例设计输出(一般都通过文字描述的方式)以及测试环境的搭建,待story的测试用例设计完后,开发人员和测试人员再进行测试用例的澄清,至此对于该story的交付内容和规格,开发和测试人员达成了一致。
(3)开发人员编码完成后,构建软件安装包,部署到开发人员测试环境中,并根据测试用例进行人工验证,如果验证都通过,则把此软件安装包作为该story的转测试包。
(4)开发人员的story转测试后,测试人员把提供的软件安装包部署到测试人员测试环境中进行验证,如果出现安装无法进行或者story基本功能不可用的情况,则进行story转测试的打回,要求开发人员重新进行该story的验证和转测试。如果安装成功并且story基本功能可用,则测试人员根据测试用例以及一些发散测试来验证story,发现问题则用提问题单的形式来要求开发进行修改。
(5)开发人员接到问题单后,进行修改,并且进行问题单的验证以及走给测试进行回归。
(6)测试人员进行问题单的回归,如果问题单已经修改好,则关闭问题单,如果没有,则打回重新修改。
(7)全部story测试完成之后进入系统集成迭代测试阶段,测试人员会根据测试用例以及一些发散的测试来验证系统的功能(这个阶段可能大部分测试用例可以用自动化的方式来跑了)。这个过程往往会重复好几次,因为每一次几乎都会有新的问题单提出,而这些新提的问题单只能等到下一个系统集成迭代测试阶段进行回归验证。
(8)如果问题单修改的质量高(都修改好了并且没有引入其它的问题)或者“运气好”(测试人员没有发现存在的问题),那最后一轮系统集成迭代测试会以无遗留问题的方式通过。如果运气不好,有新问题出现,则需要看问题的影响,如果问题影响不大,则通过“灰度”的方式进行发布。如果问题影响大,则可能临时还得出一个转测试的盘来解决该问题。
......
至此整个传统的软件交付的过程结束了。从上述过程中存在以下明显的问题:
(1)测试人员需要用文字的方式来输出测试用例。文字方式的测试用例价值很低,因为只有人才能看到,根本没法自动化。况且人要根据文字描述来测试需要有一个很重要但是基本上很难做到的前提:测试用例要描述的精确、没有歧义,并且还要保证看的人在看的时候不会出错。
(2)开发人员需要对测试用例进行测试,测试人员也需要对测试用例进行测试,造成了明显的工作量浪费。
(3)开发和测试的测试环境基本上都是靠人来搭建,需要抽调专人来负责。
(4)开发需要对问题单进行验证,测试也需要对问题单进行回归验证,造成了工作量的浪费。
(5)整个过程中开发和测试的心理压力会非常大,因为组织对于story交付进度延迟、story测试打回、问题单回归不通过、问题单的修改引入以及发布后出现问题等有严厉的惩罚措施,但是每个人对于这些问题的出现又没有一个有效的防范手段,所以几乎可以肯定每一次软件交付过程中都会出现上述的问题,当这些问题出现的时候很大程度都会影响整个版本的交付计划。
六、理想的软件交付过程
理想的软件交付过程笔者认为总结起来就一句话:关注长远价值,更少的人工参与,更高的效率。
关注长远价值就是不要为了应付某个版本的快速交付而对系统的可维护性、扩展性等方面带来负债,现在欠的债未来总是要还的,而且只会还的更多而不是更少或相等。心理学上有一个著名的破窗效应,也就是说如果某个开发人员发现系统中某块代码为了应付进度等写的很烂,后面这个开发人员也很有可能为了其它的短期利益也写出烂的代码,久而久之这个系统就没有办法维护了。
人的稳定性很差,总是处于不断地波动中,心理学里有一个回归均值理论,就是说人的表现好和表现差是交替出现的,中国也有盛极必衰,否极泰来的说法,说明事物总是在曲折中前进的。如果人工对于软件交付过程参与的太多,只能祈祷这个参与的人最近的状态比较好,不会出现很大的问题。
在软件交付过程中,如果我们发现某个地方需要人参与的太多,并且出错的几率也比较大,那这个时候得重新思考下目前这种操作方式是否合理?是否能让机器代替人自动化地来完成这些事情?
那理想的软件交付的做法应该是什么样呢?
理想的软件交付过程应该是流式的,像管道中的流水一样,即从代码的检入到最后软件包的ready都是自动进行的,中间如果某一步出现了问题,则会及时反馈详细信息给对应的人员进行处理。
(1)当开发人员完成story的编码后提交代码,一系列的自动化测试就会运行,这些测试将会测试这个系统的基本功能。如果发现哪里有问题,则会马上把问题的详细信息包括日志等反馈给开发,开发立即就可以根据这些信息进行修改。
(2)基本功能测试通过后,则会自动开始构建软件安装包以及自动搭建测试环境,并把软件自动部署到搭建的测试环境里。
(3)更进一步的系统集成测试会自动运行,这些测试会更加基于最终使用用户的立场来进行。这些测试通过后就说明版本可以发布了。
(4)全部的测试都完成后,会自动构建软件包,并在构建完成之后放到指定待发布的目录下。
上面就是笔者认为的理想的软件交付过程。在这个过程中所有人员的角色分工有点模糊了,开发人员、测试人员以及软件构建人员等都是为了一个统一的目标:怎么在保证软件交付质量的前提下让整个软件交付过程实现完全自动化。
要实现完全自动化,笔者认为需要做到以下几件事:测试用例即代码、构建即代码、部署即代码、软件发布即代码以及怎么把这几个部分串联起来,使得整个软件交付过程是流式的。当然这里有很多的技术细节需要再深入下,也请关注笔者后面的文章,会尝试对这几方面做一些思考。