在软件研发、交付的过程中会使用到大量的工具,熟知这些工具特性,可以在日常工作中快速地选择适合自己(或团队)的工具。所谓“磨刀不误砍柴工”,下面介绍软件交付过程中经常使用的工具和技术。
1.项目管理与协作
“项目”可能出现在很多行业、领域中,即便是在软件研发中,也可能是某个具体的源代码工程或者一些相关工作的集合。这里的“项目管理”主要是从项目迭代的进度、协作的角度来理解的。在软件研发过程中,不管是有3~5个人的团队,还是10人以上的团队,只要涉及多人协作的场景,本质上都需要进行“项目管理”。只不过,在具体的实践、落地过程中可以选择是否有专职的项目经理,采用物理看板还是选择相对专业的项目协作软件。为了能够让具有一定规模的团队尽量按照既定目标、工期、交付标准完成项目的迭代过程,往往需要借助相应的工具,如Jira、禅道等。
在实际的企业项目开发过程中,软件是否可以按时交付往往会受到多种因素的影响。如果能够提前为这些情况制定相应对策,识别风险,将有助于项目的按时交付。例如:
❖紧急需求,可能来自甲方或者某领导的个人意愿。
❖与项目无关的插入任务,多出现在有多个汇报对象的成员身上。
❖工作量估计的失误,过于乐观的工时评估。
❖需求、业务理解不到位,任何抱有“被动完成任务”心态的成员都会出现这种效率低下的情况。
❖交付质量标准不一致导致的不必要内部消耗,如身处上游的研发自测不充分,导致多名团队成员在某功能(或问题修复)上投入过多精力。
❖质量(QA)团队介入过晚,仓促完成质量验证过程。
任务分配是项目开发过程中非常重要的一个环节,甚至可以影响到是否能够充分利用整个团队的工作效率。与标准的工业作业流程不同,即使软件项目有再多的标准,也始终是一个脑力劳动,自然会受到主观因素影响。而软件项目的任务分配最好能够充分地考虑到每位团队成员的能力、特点和其他实际情况。以下给出三种模式。
①项目负责人直接分派。这种集中式的管理方法的任务分配效率最高,但只适用于项目负责人对所有任务和团队成员都非常了解的情况。其缺点是,如果长期发生任务与人员匹配度不够的情况,不仅严重影响交付周期,还会导致团队成员的成长缓慢甚至不必要的人才流失。
②团队成员自由领取。这体现了自由民主的管理,分配效率的高低取决于团队成员之间配合默契度(或职业素养)。优点很明显,可以维持友善、轻松的团队氛围,每个人都有机会发挥主观能动性、创新性;但若实践不当,也有可能形成互相推诿的局面。
③混合模式。根据实际情况,可以考虑结合分派与自由领取的两种方式,充分利用两种方式的优点,避免缺点。
项目看板可以帮助团队成员从项目整体的视角观察到进度、风险信息。“只见树木,不见森林”的片面、局部视角容易让团队成员陷入具体细节,而影响整体的项目交付。所以,通常建议,全体团队成员都养成每日至少检查一次项目看板的习惯,确保熟悉项目的进度信息,这将对日常的思考甚至工作习惯带来非常好的影响。项目规模相对较大或者团队成员较多的情况可以考虑创建多个不同纬度的看板,避免看板过于复杂、庞大而变得难以快速获取信息。如果有条件,可以在工位附近挂一个大屏显示器,实时地显示相应的看板。简言之,查看看板是一件很简单却容易被忽视的事情,应尽量降低团队成员查看看板的成本。
适当地引入自动化工具,简化不必要的烦琐操作。工具的采用是为了保障团队成员可以高效地协作。需要避免的情况是,为了完成某项工作需要切换、登录多个工具,甚至提交重复的表单。例如,研发用拉取请求(Pull Request)的方式提交代码时,可以方便地关联对应的问题单(issue,如功能需求、问题修复等);而当自测、代码评审(review)完成并合并后,工具可以自动将相应的issue关闭(或者设置为某种状态)。另一个比较典型的例子是,若能够在问题单(issue)(或Pull Request)中关联到代码构建出来的制品信息(镜像、Maven包等),甚至能够将程序自动部署到相应的集成测试环境中,那么对于测试人员而言,这类工具方便使用,甚至可以减少不必要的步骤和沟通成本。
2.代码管理
代码、文档都是非常重要的项目资产,出于协作、版本回溯的考虑,需要有能够具有版本管理的工具,如Git、SVN等。Git是一个开源的分布式版本管理系统,可以有效、高速地处理从很小到非常大的项目版本管理。Git是目前最流行的项目版本管理工具,在主流操作系统(Windows、macOS、Linux)上都有对应的命令行或图形化工具。
在实际使用中,Git服务往往会通过一个服务器集中提供,团队成员都会从这个服务上Pull(拉取)并Push(推送)代码;并且,所有CI/CD过程都会以这个Git服务为准。Git服务有着丰富的选项供挑选,如提供收费或者免费SaaS(Software-as-a-Service,软件即服务)平台的GitHub、GitLab、Bitbucket、Gitee等,可以私有化部署的开源项目GitLab、Gitea、Gogs等。每个团队可以结合自己的情况来选择,如代码是否可以公开、是否有内网环境隔离的需求、有多少预算等。
注意,搭建一个Git服务很容易,但长期维护并保障稳定、可用却不容易,这就需要有人对其运维工作非常熟悉;而且,随着团队规模的变大,宕机带来的影响也不可小觑。
3.代码质量管理
代码质量对于一个软件的重要程度不言而喻,代码质量管理的关键在于尽早发现并解决代码质量问题,避免质量问题流出到后续环节(单元测试、端到端(E2E)测试、持续集成、研发自测、质量测试、用户使用等)。越是在靠后的环节中发现的问题,修复时涉及的人员越多,复现问题的难度也越大,随之而来的成本越高。
自动化进行的测试包括:单元测试、端到端(E2E)测试、API测试、UI自动化等,成本依次增加。
单元测试可以很好地从函数的角度保障正确性,尤其在涉及代码修改、重构时能起到极其重要的作用;但是其关注点是项目内部的函数逻辑是否正确,对所依赖的外部组件的错误处理、兼容性等问题无法覆盖。
涉及实际运行环境中可能出现的问题则需要利用端到端(E2E)测试来保障,这种方式会自动化地搭建实际运行环境(包括所依赖的组件、中间件等),涉及更多的技术栈,可能需要较多的服务器资源,往往也会运行较长的时间。
还有一些质量活动对个人经验的依赖比较多,尤其是代码评审(Code Review)过程。代码评审是不可或缺的环节,在这个过程中往往能发现一些隐形的、可能不会直接体现在用户界面(User Interface,UI)上的问题,如代码的可读性、可维护性、复杂度、潜在的安全问题、潜在的性能问题等。但在实际中,代码评审可能由于各种原因而大打折扣,如项目交付压力、缺少了解相关代码(以及业务)逻辑的人、缺少代码编写规范而导致的无谓争执、评审过程难以体现工作量而无法与业绩挂钩导致的不重视等。
测试环节的人工测试可以借助测试用例管理工具,对项目(产品)进行“拉网式”的测试覆盖,几乎可以避免所有预想到的问题流入生产环境。这里,除了需要消耗大量的人力,随着项目复杂度的增加(主要体现在测试用例的不断膨胀上),对于涉及大量功能点的需求变动(或缺陷修复)时,进行一次“全量”测试时需要消耗的工时、人员数量可能是难以接受的,从而“被迫”选择对部分功能点进行回归验证。
最后,为了避免让“漏网”的缺陷大面积地影响用户使用,我们可以借助灰度发布技术,渐进式发布正式版本。灰度发布可以把新版本按照一定比例发布,若遇到问题,则可以快速回退;没有问题后,再全量发布。这样可以很大程度改善用户体验,甚至可以做到允许用户选择是否提前体验新版本。当然,灰度发布对项目的架构也有一定的要求,我们需要在生产环境中遇到问题时承担的风险与项目架构复杂度成本之间进行平衡。
本书将在第5章详细介绍软件质量管理。
4.制品管理
所谓制品(Artifacts),是指由代码编译、打包成的依赖包或者可执行的文件。制品文件通常以某种压缩格式存在,常见的形式包括镜像、Helm chart、JAR、WAR、NPM等。制品是软件工程的主要交付物,可以让最终用户拿来实施部署,或者可供其他开发者作为依赖库使用。为增加制品包的可识别性,一些格式的制品还支持添加元数据信息,如构建环境、构建时间、版权及作者信息、数字签名、启动入口等。文件的压缩格式可能是比较普遍的ZIP格式(如JAR、WAR等),也可能是开放容器计划(Open Container Initiative,OCI)这种特定的镜像格式。我们可以通过相应的工具来检索、下载、查看制品包的信息。
由Sonatype公司出品的Nexus是一个以保存Maven项目制品包(JAR、WAR等)的开源工具,还支持很多其他流行的类型,如镜像、Helm Chart、NPM、RPM、apt-get等。除了开源版本,Sonatype还提供商业版本,支持高可用性(High Availability,HA)。
由VMware公司开源的Harbor是CNCF(Cloud Native Computing Foundation,云原生计算基金会)的毕业项目,是一个非常强大的镜像制品仓库。如果不想私有化部署一个镜像制品仓库,可以选用SaaS平台提供的镜像服务,如Docker和GitHub提供的免费镜像仓库。