可持续集成
1、什么是持续集成? 集成,就是一些孤立的事物或元素通过某种方式集中在一起,产生联系,从而构成一个有机整体的过程。知识经济的社会,集成已经成了很重要的一个名词。各行各业基本都会用到集成。而在软件行业中,集成并不是一个简单的“搬箱子”的过程。因为软件工业是一个知识生产活动,其内在逻辑非常复杂,需求又很难一次性确定,完成的产品与最初的设计往往相差很远。
敏捷宣言中就有一条是说响应变化重于遵循计划。而且由于软件行业的迅猛发展,软件变的越来越复杂,单靠个人是根本无法完成。
大型软件为了重用及解耦,往往还需要分成好几个模块,这样集成就成了软件开发中不可或缺的一部分。
在《持续集成》一书中,对持续集成的定义是这样的:持续集成是一种软件开发实践。
1.1 持续集成定义
持续集成-CI(Continuous Integration):对软件项目进行持续的自动化的编译打包构建测试发布,来检查软件交付质量的一种行为。
1.2 组成
自动编译+自动代码检查+自动打包+自动化测试+自动部署
在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以多次。每次集成会经过自动构建(包括自动测试)的检验,以尽快发现集成错误。
自从在团队中引入这样的实践之后,Martin Fowler发现这种方法可以显著减少集成引起的问题,并可以加快团队合作软件开发的速度。
2、持续集成能给团队带来什么好处? 如果想要谈持续集成的好处,那么我们应该先谈谈没有采纳持续集成,项目会出现什么问题。
总体来说,没有采用持续集成的项目一般会面临下面四个问题:
2.1 未采用持续集成
①、没有一致的可部署的软件。只有在完成集成测试、系统测试后,才能得到可用的软件,整个过程中只有最后时刻才能拿到可运行软件。集成活动不一定在一个标准的构建机器上生成, 而是在某个开发人员的机器上构建的,那么可能存在在其他机器上无法运行的问题。
②、很晚才发现缺陷,并且难以修复。实践证明,缺陷发现的越晚,需要修复的时间和精力也就越大。从上一个可工作的软件到发现缺陷之间可能存在很多次提交,而要从这些提交中找出问题并修复的成本会很大,因为开发人员需要回忆每个提交的上下文来评估影响点。
③、低品质的软件。 由于集成时每次包含的代码很多,所以大家的关注点主要都是如何保证编译通过、自动化测试通过,而往往很容易忽略代码是否遵守了编码规范、是否包含有重复代码、是否有重构的空间等问题。而这些问题又反过来会影响今后的开发和集成,久而久之集成变得越来越困难,软件的质量可想而知。
④、项目缺少可见性。
2.2 采用持续集成
而通过持续集成的活动,可以实现以下价值:
①、减少风险。缺陷的检测和修复变得更快。软件的健康程度可以测量;
②、减少重复过程。让人们有时间做更多的需要动脑筋的、更高价值的工作。通过对重要过程自动化,克服项目中某些成员对实现改进的抵制;
③、在任何时间、任何地点生成可部署的软件。对客户来说,可以部署的软件是最实际的资产;
④、增强项目的可见性。集成就像我们项目的一面镜子,通过这面镜子能够快速的了解项目目前的状况、存在的问题;
⑤、对开发团队的软件产品建立起更强大的信心。它能够帮我们有效的决策,注意到项目进展的趋势;
2.3 Martin Flower为持续集成总结了以下一些原则:
①、维护一个统一的代码库;
②、每天都必须向主干提交代码;
③、每次提交都应立刻在集成环境进行构建;
④、自动化构建;
⑤、自动化测试;
⑥、自动化部署;
⑦、快速、持续构建;
⑧、构建环境务必于生产环境保持一致;
⑨、访问权限对团队成员保持公开透明;
3、持续集成都包括哪些要素? 一个最小化的持续集成系统需要包含以下几个要素:
①、版本管理系统:项目的源代码需要托管到适合的版本管理系统中,一般我们使用git作为版本控制库,版本管理软件可以使用github、gitlab、stash等。
②、构建脚本:每个项目都需要有构建脚本来实现对整个项目的自动化构建。比如Java的项目就可以使用gradle作为构建工具。
通过构建工具实现对编译、静态扫描、运行测试、样式检查、打包、发布等活动串起来,可以通过命令行自动执行。
③、CI服务器:CI服务器可以检测项目中的代码变动,并及时的通过构建机器运行构建脚本,并将集成结果通过某种方式反馈给团队成员。
4、从零开始构建持续集成 CI = 高效的构建+全面有效的测试+合理的流程规范+工程师文化+ROI
1、高效的构建
①、高效的构建:主干开发是快速推进CI的有力基础
核心:源代码、测试用例、配置和数据统一管理
优势:解决merge回主干困难,回归成本高的问题
解决随着项目增多,分支增多,管理越来越难的问题
修复BUG,可以达到修改主干,多出都可以fix的效果
解决QA只保证单独分支质量,忽视merge后主干质量的问题
②、高效的构建:需要工具支撑
版本控制:git&SVN
代码管理:gitlab私有部署
基础环境:虚拟机、docker、kubernetes
自动构建:jenkins
反馈机制:邮件&短信&微信&钉钉
具象方式:打造符合团队需要的pipeline
2、全面有效的测试:测试存在于项目周期各个阶段
①、需求与设计:PM/DEV/QA
需求评审
需求变更
设计评审
②、开发与测试:DEV/QA/PM
code review、单元测试
测试方案、测试用例、BUG管理、风险评估
功能测试:冒烟、集成、系统、验收
性能测试、安全测试、容灾测试
线上验证、探索性测试
③、上线与线上:OP/QA/DEV/PM
线上验证
业务监控
用户反馈
产品评测
PS:缺陷发现越早,修复成本越低,反之则越高
3、合理的流程规范
①、代码提交规范
本地开发
本地编译(自测,check out)
提交至当前主干(change log简洁明确)
主干编译(测试,check out)
②、注意事项
提交至主干前做好本地编译、自测
提交前解决代码冲突
提交时及时关联和添加描述
提交后关注代码扫码结果
提交后关注主干集成构建结果
构建没问题后及时合并
③、遵循原则
主干构建失败停止提交代码,直至构建成功
优先修复失败的构建,修复问题
如果构建不能快速修复,执行回滚
4、工程师文化
①、提高对交付软件质量保障的意识(测试是核心)
②、树立优先处理失败的构建的意识(优先程度最高)
③、培养团队工程师文化(流程、质量、沟通、职业素养)
④、优化团队管理、流程各方面,做到精简,避免过分强调流程、避免面子工程、做好资源协调
5、ROI(投资回报率)
①、从0到1,可接受的投入的资源成本
入门阶段可以考虑持续编译打包,及时反馈代码版本库的编译问题冲突问题(快速正向的反馈);
②、从1到2,选择对整体交付质量,速率提升最高的选项
可以选择性价比较高的持续部署和代码检查,定时code review,减少手工部署和代码级别的BUG造成的风险;
③、从2到3,面临的问题越来越多
挑战:
构建任务的不断增加,执行速度的下降,整体效率的降低,成功率低于期望值;
自动化测试脚本维护量大,依赖于基础测试环境和测试数据的稳定性;
解决方案:
增加任务构建执行机,减少排队现象(多任务分布式构建);
拆分耗时较长的任务,减少单个任务执行时间,解耦;
将自动化测试放在稍后的阶段实施,分层设计,轻量的UI和重点API层automation,是目前业内较好的自动化测试实践结果;
④、从3到N,不断扩展带来的挑战和期望收益提升
不同团队项目类型、技术栈构成、关注点、工作习惯不同,要求CI具备高度灵活性和定制化;
需要持续不断的资源投入;
团队自发适应、不断调整和优化方案以及流程;
5、持续集成一般都包含哪些任务? 持续集成并不是说只要代码能编译通过就是集成成功,我们已经把每次集成都看做一次完整的测试。任何迁入到代码库中的代码都应该是可以部署到产品环境的。
拿一个Java项目为例,持续集成一般执行的任务有:
①、代码静态扫描:通过静态扫描确定代码的一些潜在bug,比如未被使用的变量等。
②、代码样式检查:团队一致定义出需要遵循的编码规范,并通过一些插件对迁入的代码进行样式合规性检查,防止不守规范的代码进入版本库。
比如方法名首字母小写、类的首字母大写、if关键字后面需要加空格等问题都可以纳入到样式检查中。
③、单元测试、集成测试、系统测试:通过运行自动化的单元测试、集成测试、系统测试可以有效的保证迁入代码的质量。一旦有测试失败,开发人员就需要快速反应进行修复。
④、测试覆盖率检查:一般项目会有个测试覆盖率指标(比如80%),如果代码达不到这样的测试覆盖率,就不允许代码迁入。这样可以保证开发人员在新增功能时也要为新加入的功能编写自动化测试。
⑤、编译打包:确保没有任何语法错误,生成构建产出物。
⑥、发布: 将通过完整构建的产出物放置到产出物仓库,以便进行后续部署。
这些任务都必须是能通过命令行自动完成的,不同类型的项目任务略有不同。
6、持续集成这些任务应该遵循什么顺序? 其中有一个重要的原则就是fail fast,即快速失败。一般会把运行时间短的、价值大的任务放在前面,而运行时间长的任务放置到后面。
因为构建成功的标准是所有的验证都能够通过,那么执行时间短的任务放在前面能更快的得到反馈。
7、为什么我们组搭建了持续集成服务器,并且还派专人看守CI,但是感觉项目并没有明显的改善? 并不是说搭建了持续集成服务器就说明团队能成功运行持续集成了。持续集成是一个实践,所以大家要遵循一些原则。
大家可以先思考一下问题:
①、在CI服务器上多久会看到一次集成?
②、CI服务器的集成结果是绿色居多(指构建成功)还是红色居多(指构建失败)?
③、当构建失败后,团队成员有没有第一时间修复构建,有没有在构建失败的情况下依然在提交代码,在提交代码之前有没有进行本地的私有构建?
从这些问题可以引申出持续集成中需要遵循的一些原则:
①、经常提交代码
②、不要提交无法构建的代码
③、立即修复无法集成的构建
④、编写自动化的开发者测试
⑤、必须通过所有测试和审查
⑥、执行私有构建
⑦、避免迁出无法构建的代码
页:
[1]