APP下载

持续集成在敏捷开发模式中的应用探析

2023-06-12袁宜霞

电脑知识与技术 2023年11期
关键词:自动化测试

袁宜霞

关键词:敏捷开发模式;持续集成;自动化测试;CI流水线

0 引言

随着互联网时代的到来,传统的瀑布式开发无法应对需求快速变化的缺点越来越明显。面对市场商机的竞争情况,各大企业需要快速上线产品并获得市场反馈,所以各大企业普遍采用敏捷开发模式[1]。敏捷开发是以用户需求为核心,把一个大项目拆分为多个可以独立运行的小项目[2],在研发过程中,软件始终处于可使用状态。在现有产品基础上,研发团队通过增加代码来丰富功能和优化用户体验,每个团队成员每天都在生成和上传代码。未经过验证的代码合并后,如果不能快速检查发现问题,会影响各自的功能或关联模块,而如果每个开发人员都手动执行来检查问题,又会影响效率,特性的高频率交付与软件质量之间的矛盾日渐尖锐,如何平衡两者成为研发团队需要重点解决的问题。持续集成[3]就是解决这一个问题的利器,其采用高频率自动化检查代码方式,減少了手工执行错误,避免了重复性劳动,且更快地发现错误提高了产品质量,是一种常见的敏捷工程实践方法。增量代码只有彻底解决持续集成过程中发现的问题才能通过持续集成的验证。

本文制定了一套持续集成的流程,介绍了本地IDE、合并请求MR和CI流水线等阶段的具体实践过程,并详细阐述了实践过程中的关键点。

1 持续集成的流程

为了同时兼顾质量与效率,在提高发布频率的情况下保证可靠性,持续集成在代码集成、功能测试、部署发布、基础设施架构管理等各个环节都应该有全面的自动化监控手段,尽量避免人工介入,图1是一套持续集成的流程。

1.1 本地集成开发环境IDE 阶段

开发团队都具有版本控制功能的代码库,各大公司一般使用SVN或者Git对代码进行版本管理。开发人员在个人工作区完成代码开发后,先执行自动化验证集,用于验证自己修改的代码质量是否达标,只有通过了自动化验证才能push代码到主干。自动化验证包括本次增量以及相关代码的单元测试和代码规范扫描。

1) 单元测试

单元测试是指对软件中的最小可测试单元进行检查和验证,可以是函数级、方法级、类级或者功能模块级,本地IDE环境执行的仅仅是本地增量代码的单元测试。单元测试用例的编写者既可以是开发人员也可以是测试人员:开发人员编写用例的优势在于熟悉自身编写的开发代码,加上拥有较强的编程技能,所以单元测试编写覆盖率和效率都比较高,劣势在于开发人员的开发时间紧张,普遍缺乏测试思维且代码自写自测无法达到绝对的客观;测试人员编写用例的优势在于具有较强的测试思维可以保证覆盖率,借由编写用例的机会能更好地了解代码架构和实现流程,有利于后续的功能测试,劣势在于代码实现能力相对较弱,效率会比较低。在各个业务线中,可以根据自身团队人员和产品特点来实际情况来确定单元测试用例的编写者。

不同编程语言使用不同的单元测试框架,比如Java语言普遍使用Junit或TestNG[4],Python语言普遍使用Unittest或者Pytest[5]。评估单元测试的重要标准是代码覆盖率,需要尽量覆盖全部的开发代码,常见的覆盖包括语句覆盖、判定覆盖、条件覆盖、判定-条件覆盖、条件组合覆盖和路径覆盖。

2) 代码规范扫描

代码规范扫描是指不需要编译过程,通过词法分析、语法分析和抽象语法树分析等技术手段直接扫描源代码,以便检查代码是否满足规范性和是否有漏洞。针对不同开发语言,业界有多种不同的代码规范扫描工具,持续集成可以依据是否开源、适用的编程语言、扫描结果展示、扫描速度、扩展性和可维护性等方面选择几种工具进行接入以达到更好的扫描效果。例如Findbugs能扫描Java代码,PCLint和Cppcheck能扫描C/C++,golangci-lint 能扫描Go 语言,Pylint 和Flake8 能扫描Python,ESLint 能扫描JavaScrip 和NodeJs,Coverity Prevent和腾讯开源的TScanCode能扫描C/C++、C#,Sonarqube 开源且能支持Java、Python、PHP、JavaScript、CSS等25种以上的语言的扫描等[6]。

1.2 合并请求MR 阶段

本地验证通过后,开发人员将本地修改的代码与主干上已经更新的代码进行合并,再执行一次合入前检查,确保本地修改的代码与主干上最新代码的合并没有质量问题。这次质量验证会执行产品全量代码的单元测试、集成测试和代码扫描规范,其中任意一项验证未通过都会结束合并请求并通知开发人员进行修改。与本地IDE阶段相比,单元测试和代码扫描规范由本地增量和相关代码变成全量代码,新增了全量代码的集成测试。集成测试的主要是通过模拟真实的用户场景,从最终用户的体验出发对多个已完成单元测试的模块进行模块间调用和集成,对被测系统的集成性和数据完整性进行测试,其重点关注模块间的接口和集成后的功能,常见的有针对API调用的接口测试和利用Selenium[7]和Appium[8]等测试工具来实现的UI自动化测试等。当通过合入前检查后,本地修改代码才正式合入主干。

1.3 CI 流水线阶段

市面上有很多的CI 工具,无论是新兴轻量的工具Drone,还是老牌的Jenkins工具都原生或通过插件方式支持了配置文件管理流水线[9]这一特性。这样一方面不再需要一个Web页面专门用于流水线管理,减少了维护成本,另一方面,将流水线配置集成在源码仓库中,享受与源码同步升级的方式,使得CI 流程也能使用Git 的版本管理进行规范与审计溯源,如下是关键阶段。

1) 提交构建

持续集成服务器发现主干代码变更后,立即开始执行提交构建,运行自动化质量验证。如果这次构建失败,则直接阻塞结束本次构建,研发团队负责人立即着手修复,为了尽快获得软件质量反馈,提交构建的执行时间不应超过团队规定时间,比如15分钟,所以这个阶段自动化验证的是运行速度较快且质量高的测试用例,主要包括:增量代码和相关依赖代码的单元测试用例、安全/漏洞扫描、BVT核心准入测试等,其中安全/漏洞扫描工具主要有Burp Suite、Nessus、AWVS等[10]。

2) 次级构建

这个步骤在流水线里是可选步骤,当自动化测试用例的规模增加到一定程度,无法在团队规定时间内完成提交构建的所有质量验证时,可以在提交构建通过后立刻启用次级构建。通常把运行时间长且不经常失败的测试用例放到次级构建,在执行次级构建时并不阻塞其他工作任务开展。次级构建会执行全量的单元测试和集成测试,如果次级构建验证失败,也要求立即通知研发团队负责人进行修复,并通知其他开发成员在问题修复前,不能再次提交代码。放入次级构建的自动化测试用例主要包括执行时间长耗费资源多的或者优先级低出错可能性低的用例。

3) 编译打包

通过提交构建和次级构建的基础质量验证后,当前主干的代码就是一个可以直接部署的版本,将这个版本的所有文件进行编译打包存档到生產服务器,做好发布准备。

2 持续集成流程的关键点

2.1 主干开发,频繁提交代码

研发团队内的开发人员从主干上拉出个人分支,完成开发任务和通过单元测试后,以每天至少一次的频率将其新增代码合并到主干中。主干开发可以大大加快产品迭代的效率,但是也会让新完成的功能特性无法得到全面的手工测试和验证,所以要实现主干开发、频繁提交,必须实现如下策略:

1) 研发团队采用小批量开发模式,把项目拆分成多个小项目后,能够较短时间内实现小项目的需求。

2) 团队积累全面且有效的自动化测试用例,包括全量的单元测试和集成测试,拥有极高的测试覆盖率、准确率和有效率,才能保障主干代码质量的稳定,持续集成过程不需介入人工验证也可以让团队对代码的质量比较有信心。

3) 提交代码到主干前,开发人员进行代码走查和审核能提高新增代码的质量,有助于提升新增代码通过各种自动化验证的概率,确保代码能顺畅地合并到主干中。

4) 构建和测试过程应该在15分钟内完成,过长的等待时间会提高将代码合并到主干的成本,提高了持续集成效率才能提升团队的研发效率。

5) 高度自动化且精准的线上及灰度监控能力能为采用持续集成的项目进行质量保底。通过持续集成验证发布出去版本一旦有严重缺陷,强大的线上灰度监控能力能让团队在短时间内发现异常,停止新版本发布,并紧急修复缺陷后快速进行验证再次发布。

2.2 团队分支也需要持续集成

研发团队有时也会采用分支开发集成发布的研发模式,比如重大底层重构类技术需求或者是数据版本升级,研发团队会从主干上拉出团队分支,多人在该分支上频繁提交和构建代码,开发人员在本地完成开发任务后,把代码合入团队分支。这种团队分支通常会与主干并行存在较长一段时间,在分支验证通过后直接在分支上进行灰度发布,灰度发布的数据稳定后把团队分支代码合入主干,再跟随主干进行全量发布。针对这种团队分支,团队将其设置为保护分支,仅允许在所有测试通过后才合并拉取请求,并且跟主干一样所有的代码提交自动触发CI流水线,强制执行持续集成以保证团队分支代码质量的稳定。

2.3 单元测试由开发人员负责测试人员辅助,集成测试由测试人员负责

单元测试的对象是模块内部的程序,为了消除局部模块的功能和逻辑上的缺陷,在持续集成中采用白盒自动化测试方法。由熟悉自己实现的功能代码的开发人员负责单元测试是事半功倍的,鉴于开发人员对测试知识的不足,测试人员负责单元测试代码的走查。对于重点功能的单元测试,由开发和测试采用结对编程的方式完成能达到质量和效率的平衡。集成测试的对象是模块间的集成和调用关系,采用白盒测试和黑盒UI自动化测试方法。这类测试需要对整个程序功能和实现方式比较了解,专业的测试人员负责比较合理。在项目实施过程中,采用自顶向下方式和自底向上方法结合的集成测试用例编写能达到发现缺陷时机和编写成本的平衡。

2.4 测试用例分级处理

在实际项目发布时,存在小范围的灰度发布和针对全部用户的全量发布两种形式。一般情况下,集成测试用例的自动化执行是持续集成中最耗时的步骤,采用用例分级方式能进一步提升发布效率。对于集成测试用例,标注1级为程序最重要的用例,灰度发布和全量发布都需要执行;标注2级为次重要用例,灰度发布不需要执行仅在全量发布时执行;标注3级为不稳定用例,需要优化代码提高稳定性。

3 结束语

综上,持续集成将软件交付过程中开发、测试和运维的环节打通,通过自动化测试与监控来提高研发效率和质量,其主要特点如下文。

3.1 构建自动化

持续集成提供让软件自动编译和链接到可执行文件的能力,在运行集成构建时,会识别出代码冲突、编译错误等基本问题,这类低级别高影响的问题需要在代码合并后快速被发现和处理,所以需要高频的自动化构建。

3.2 测试自动化

在迭代过程中,研发团队需要重新测试之前版本中的可行功能,保证产品功能的稳定性。所以,在开发代码的同时,团队也需要编写对应的单元测试和集成测试用例,在构建产品增量代码时自动触发这些不断累积的测试用例的执行,能更早发现功能性和逻辑性缺陷,减少项目提交测试后的代码缺陷。

3.3 丰富的插件应用

持续集成系统能应用丰富的插件来提高系统的稳定性和安全性,比如代码静态扫描和安全扫描等都可以嵌入到持续集成中,一方面保证了功能的质量,另一方面也促使团队优化系统架构、减少冗余代码、提升系统安全性,让交付的产品更加完美。

猜你喜欢

自动化测试
浅谈空调控制器自动化测试