持续集成---减少持续集成的时间

持续集成领域,一个产品的发布往往都有自己的过程周期(lifecycle),大体都会划分为:构建->部署->测试->发布等几个重要阶段,其中测试是发布产品前不可或缺的重要阶段,是产品质量的保证。而能让持续集成奏效,除了要求测试脚本更充分健壮,还要求测试脚本运行得更快更好。这点对于小型项目而言可能显得无关紧要,毕竟大多小项目的测试脚本不过百条,验证点不过千“点”;但对于一个大型项目而言,测试代码源文件可能成百上千,执行完所有的测试可能要等很久,而苦等之后的结果却可能是满眼的failure, 于是如果提高测试执行速度成为迫切需要解决的问题,试想把测试阶段从2小时压缩到1小时,再从1小时压缩到30分钟,每次时间压缩带来的不仅是技术人员本身的成就感,更是对整个产品发布过程体验的改善。

  那么如何加速测试的执行呢?提起速度,我们立马可能联想到“性能”调优的步骤:先进行tuning,然后找到问题的瓶颈所在,最后逐个击破。本文暂不讨论如何进行这些步骤, 而是基于C++和Java为语言案例,TestNG和Google test为测试框架,Jenkins为持续平台做分析,从以下六个层次提出提高测试执行的一般方法:

  硬件资源层次

  工欲善其事必先利其器,提高硬件(CPU、内存、磁盘等)配置是改善执行速度的“硬”方法,硬件资源的优化不应仅仅局限在单机自身的各项指标提升,在需求不断提高的情况下,可以考虑实施虚拟机、分布式集群等方式来进一步获取更优的硬件资源,当然,涉及分布式执行时,可以借助以下持续集成平台层次的“软”实施来共同作用。

  另外,在硬件资源紧张的情况下,不同项目或者不同团队可能不得不复用一套测试环境,造成可利用资源更为紧张,此时可以错开时间测试(例如A项目组测试定时在凌晨0点启动,B项目组定时在凌晨2点)以提高速度。

  语言编码实现层次

  测试代码本身也是代码,显而易见,如果代码编写时注重效率,速度上肯定有所收益。这点可能需要“纠结”于一些日常的编码细节:例如Java中Stringbuffer和Stringbuilder的比较;C++中是i++和++i的比较。这种语言层次提高效率的文章书籍很多,这里不做过多描述。在语言编码层次上最重要的不是这些语言细节,而是避免一些消费时间的测试代码设计,减少不必要的耗时操作,例如以下几点:

  (1) 冗余的日志信息,不合理的日志级别设置等

  输出日志带来的磁盘频繁访问必然让速度下降,所以在保证日志信息充足的前提下,尽量减少日志,或者只记录失败测试的日志(毕竟对于测试者而言很少去关注成功日志),可以让测试加快。

  (2) 不合理的等待

  用户执行完某个操作,必须等待某条件的发生(例如DB里面插入一条新数据)进而执行后续动作是测试中经常面对的场景,那么等待多久成为需要考虑的问题,假设用TimeUnit.MINUTES.sleep(1)等待一分钟,在10秒即可满足条件的场景下浪费的就是50秒,所以这里必须去考虑合理sleep的时间来兼顾对资源的消耗和运行速度的影响,同时在等待方式上也可以考虑是采用循环短时间条件等待或异步通知的方式去进行。

  (3) 用例的过程

  先执行完所有测试步骤,然后做对所有步骤做一次性校验,还是做完一步校验一步,这两种方式的速度在不同场景下有所不同,所以需要权衡;相类似的,对于需要获取DB连接的用例,是每条都执行获取DB连接然后释放连接,还是所有用例执行之前获取连接,所有case执行完之后释放连接也会对执行速度有所影响。

  构建测试脚本层次

  对于一个大型项目,源文件的数目庞大或依赖的dependency过多导致代码编译占用大量时间,如何提高编译代码的速度?除了使用更好的磁盘,注重代码编写时对编译速度的影响,还可以针对不同的语言采取不同的有效策略,例如针对C++, 使用make命令编译项目时,可以加上参数-j来并行编译项目。-j参数的含义可以参考下文:

  -j [jobs], --jobs[=jobs]

  指定同步运行的作业(命令)的数量。如果有一个以上-j选项,那么只有最后一个有效。如果-j选项没有参数,那么编译过程就不会限制能够同步运行的作业的数量。

  需要说明的是,编译过程可能要求特定的顺序而导致并行编译失败,如果遇到这种问题,可以先并行、后串行(去掉-j)重复执行一次以解决。

  而对于java,Maven 3 开始支持并发build,提供了以下几种常见方式:

  mvn -T 4 clean install # Builds with 4 threads

  mvn -T 1C clean install # 1 thread per cpu core

  mvn -T 1.5C clean install # 1.5 thread per cpu core

  同时使用maven管理java项目常出现时间消耗在依赖jar的下载上,此时可以检查是否有冗余失效的repository配置、较长的下载timeout时间设置、所选择repository的连接速度等,甚至在不同测试环境下可以使用 profile来管理repository来加速测试脚本构建。

 测试框架支持层次

  在测试框架支持层次上,应该充分运用框架本身提高的丰富功能来提高测试执行速度,以Java测试框架TestNG为例:

  (1) 利用timeout控制失效等待

  如果某个测试用例等待某条件的触发而陷入长时间等待,等待的时间过长往往对于用例本身而言已失效,特别是当条件永远无法满足时。因此需要控制用例执行允许的最大timeout时间。TestNG可以给test或者test suite设置 timeout时间,分别控制具体某个或一组(testing.xml配置)自动化测试用例执行的最大允许时间:

  1. @Test(timeout = 1000)

  2. testng.xml : <suite name="Module Test" parallel="none" time-out="200000">

  (2) 利用@BeforeTest、@BeforeClass等条件注解,减少无意义测试

  测试的顺利完成都需要满足很多基础条件,例如需要测试环境就绪, 如果不使用@before类标签,则当条件不具备时,仍然会执行完所有的用例,必然带来巨大的时间浪费,因此使用@before类标签可以避免无意义的测试,@before标记的方法一旦失败,后续的相应的测试不会继续进行。

  (3) 使用框架自带的多线程支持

  例如对于TestNG自身,可以在testng.xml中设置parallel参数来指定是否并发以及并发的级别:methods|tests|classes,除了测试框架自身外,软件项目管理工具也可以提供多线程支持,例如maven的测试组件maven-surefire-plugin,提供了并发参数的设置:


<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-surefire-plugin</artifactId>

<version>2.16</version>

<configuration>

<parallel>methods</parallel>

<threadCount>10</threadCount>

</configuration>

</plugin>

  持续集成平台层次

  现在市场上存在不少持续集成平台,大多持续集成平台支持并发执行用例然后汇总、发布测试结果,从而最大化提高测试执行速度。而并发执行的前提是测试代码本身及测试代码的组织支持并发,如果测试本来就含有多个模块,那么直接并发运行多个模块,最后汇总结果即可。如java以testng.xml为模块,gtest以makefile为模块,所以相比较顺序执行4个模块,并发使用4个Job并发执行,那么时间压缩可以达到4倍。在实际应用中,即使在同一个模块,我们仍然面对自动化测试用例数目过多运行速度过慢的问题,此时,可以考虑将单一模块拆分成子模块,对于Java而言较简单,配置下测试套件的xml即可;而对C++而言,如果不允许直接复制粘贴原有的makefile,就需要重新设计makefile以复用, 例如将makefile中编译的test cases定义分拆到多个makefile(如下图测试模块1的makefile引用了共用的makefile并添加了自己的测试用例)中,然后并发执行多个makefile。

  为并发执行多个job, 持续集成平台必须提供必备的支持,以Jenkins为例,可以使用multijob插件来实施,配置多个测试模块同时进行.

  并发完测试后,讲所有测试结果汇总到一个地方,然后使用xunit plugin来汇总结果(如下图),它可以汇总多个文件,且支持cpptest、,gtest等输出结果格式。

  过程改进层次

  在产品的持续集成生命周期中,可以将测试拆分成两部分放在两个阶段:基本功能快速校验阶段(fast fail)和基本功能之外的全面测试阶段。如果产品在第一阶段最基本的功能都无法通过,那么部署之后进行全面测试纯属浪费时间,这个阶段的引入可以快速的校验产品是否有必要开展全面测试。这点类似与测试用例中添加了@before类标签所带来的收效,不过更宏观且阶段划分的更清晰。

  原有过程:构建阶段->部署阶段->测试阶段->发布阶段

  细化后过程:构建阶段->部署阶段->基本功能快速校验阶段->全面测试阶段—>发布阶段

  这种过程优化可以利用持续集成平台来支持,例如对于Jenkins系统,可以使用multijob插件,将基本功能快速校验和全面测试阶段分列在不同的phase即可,执行效果如下:

  结论

  通过上面由微观到宏观六个不同层次的分析可知,要加速测试用例的执行是一个系统的过程,单靠某一方面分析可能有所偏失,并不能将测试用例的执行速度发挥极致。同时,本文针对不同层次的分析也没有提供step by step的方式描述每一个细节,只是点到为止,所以读者可以根据自己采用的语言、测试框架、持续集成平台做类似更有针对性的分析,相信在综合不同层次的综合调优后,可以让持续集成实施的更快、更好。

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-10-22 11:12:40

持续集成---减少持续集成的时间的相关文章

超大型系统的持续集成与持续交付解决方案与阿里宙斯盾

作者简介:鲁小川,09年本科毕业于浙江大学软件学院,之后就一直就职于阿里巴巴B2B质量保障部,目前是云效持续集成与持续交付解决方案的负责人. 以下内容根据演讲嘉宾分享以及PPT整理而成. 今天分享的议题是<超大型系统的持续集成与持续交付解决方案及案例分析>,主要就是和大家聊聊阿里巴巴B2B技术部这几年来在持续集成与持续交付上实践经验,以及为什么要做宙斯盾系统平台产品来支撑持续交付.宙斯盾平台在阿里内部经过了5年多的积累沉淀,现在已经对外服务输出了,对外服务产品的名字叫做云效平台,后面还会介绍云

产品迭代发布如何更快速?阿里持续集成与持续交付实践之路全解析

2017年5月9日,云效平台资深研发工程师向禹通过直播分享了<持续集成与持续交付实践之路>.他从云效背景.云效方案.云效价值三个方面进行了分享.他主要分享了持续集成持续交付的解决方案和案例,并且对大型系统如何实现持续集成.持续交付.进行产品迭代发布进行了详细介绍. 以下内容根据直播视频整理而成. 云效背景--阿里巴巴<持续交付>之路 大应用下的交付 在七八年之前,阿里巴巴的B2B一直沿用瀑布的模式来进行项目管理,当时已经感觉到瀑布模式对应用持续快速的发展产生了很大的影响.并且当时很

让IT跟上业务思考的速度--从持续集成到持续交付

通过 7 个持续交付最佳实践,给读者一个思路,无论是建设持续交付能力,还是在进行持续交付平台的选型,都能够在业界经验的基础上走向更为正确的道路.同时,本文还引入了持续交付成熟度模型,目的是想帮助企业,把一个想象中全面而复杂的交付流程进行切分,按照环节和成熟度等级展现,将实现持续交付能力之路变得更为清晰.更可操作.有助于企业建立良好的期望和愿景,并开展切实可行的行动. 市场和业务瞬息万变,企业的 IT 部门必须面对产品上线周期不断变短的事实,也就是说,需要建立产品交付反馈圈,并让这个闭环圈的反馈速

从持续集成到持续交付——Docker Cloud概览

本文讲的是从持续集成到持续交付--Docker Cloud概览[编者的话]本文介绍了Docker Cloud的概况,以及如何使用Docker Cloud改进我们的持续集成和持续发布的流程.也指出了目前Docker Cloud还存在的功能方面的问题. 容器化(Docker容器),持续集成(CI),持续部署或持续交付(CD)是简化DevOps工作的终极方案.这展示了一个未来的场景:当代码被提交到代码库之后,所有的后续工作包括编译.配置.交付和部署,甚至是高可用性都是完全标准化和自动化的.从这个角度我

直播|超大型系统的持续集成与持续交付的解决方案及案例分析

人人都在谈敏捷开发的时代,大型系统要保证产品质量,实现快速迭代却变得不易.那么大型系统如何实现持续集成持续交付,进行产品迭代发布呢? 9月7日晚上20:00阿里巴巴高级测试开发专家--鲁小川,将在阿里云•为大家现场直播,提供解决方案!与此同时,直播现场特别设置答疑环节,让观众与专家进行一次零距离的沟通交流! 直播详情 直播时间:2016-09-07 20:00:00 直播地址:http://yq.aliyun.com/webinar/play/69 (报名之后才能收看直播哦~) 直播内容 主题:

谈谈持续集成,持续交付,持续部署之间的区别

经常会听到持续集成,持续交付,持续部署,三者究竟是什么,有何联系和区别呢? 假如把开发工作流程分为以下几个阶段: 编码 -> 构建 -> 集成 -> 测试 -> 交付 -> 部署 正如你在上图中看到,「持续集成(Continuous Integration)」.「持续交付(Continuous Delivery)」和「持续部署(Continuous Deployment)」有着不同的软件自动化交付周期. 持续集成 持续集成是指软件个人研发的部分向软件整体部分交付,频繁进行集成

企业如何实现持续集成与持续交付

        持续集成则是敏捷开发具体实践的一个建议环节,通过这个环节可以在研发过程中快速得到代码质量的反馈.Martin Fowler对持续集成是这样定义的:持续集成 是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过自动化的构建(包括编译,部署,自动化测试)来验证,从而尽快地发现集成错误.自动化构建验证可以大大减少集成的问题,让团队能够更快的开发内聚的软件.         持续交付(Continuous D

什么是持续集成?持续交付?持续部署?

作者: 阮一峰 互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI). 本文简要介绍持续集成的概念和做法. 一.概念 持续集成指的是,频繁地(一天多次)将代码集成到主干. 它的好处主要有两个. (1)快速发现错误.每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易. (2)防止分支大幅偏离主干.如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成. 持续集成的目的,就是让产品可

云效平台:企业级互联网架构下的持续集成与持续交付实践

摘要:本文的整理自2017云栖大会-南京峰会上阿里云高级技术专家鲁小川的分享讲义,讲义主要分享了阿里云云效平台对于企业级互联网架构下的持续集成与持续交付的实践经验,首先介绍了阿里云云效平台的起源,之后对于企业并发研发项目交付流程存在痛点进行了介绍,并介绍了云效平台针对业务痛点所能够提供的服务和能力,并且结合实际案例分享了云效平台持续集成和持续交付实践. 在2017云栖大会-南京峰会上,阿里云高级技术专家鲁小川做了题为<企业级互联网架构下CI/CD实践>的精彩分享.所谓CI/CD也就是持续集成与