随着DevOps理念越来越深入人心,持续集成,持续部署已经成为很多公司技术团队努力追求,且不断完善的目标。在持续集成和持续部署的流程中,自动构建和自动部署一般是技术团队选择优先实现的目标。有了持续交付的流水线,我们要关心的就是流水线上产品的质量了。从代码编译打包前的单元测试,代码扫描测试,到构建后的功能测试,接口测试,UI测试,安全测试等都有一些社区和商业解决方案。
除了以上这些测试以外,性能测试往往是技术团队比较靠后去考虑放到持续交付流水线上的一环。和很多团队沟通过这个问题,总结起来原因有以下几个:
1.团队对性能测试重视不足,往往到了上线之前才想到要对系统性能做一个全面的了解。听起来这好像是一个很初级的问题,但是这确实真实存在于很多公司中的现象,尤其是一些快速发展的初创公司,很多时候系统的性能瓶颈都是直接在生产环境由用户发现的。所以往往性能测试的需求都是在真实业务中受挫后才提到日程上来。
2.性能测试,尤其是服务器端的集成环境性能测试准备环境往往比较复杂。即使已经有了比较成熟的被测系统自动部署,测试环境的准备也是很让人头疼的,尤其是被测系统承压能力比较强的,需要进行大并发性能测试的团队,比如一些电商,物联网公司。我们经常可以看到一个测试团队为了做一次大规模的性能测试,首先花几天的时间准备测试机,安装测试工具配置集群;再花一些时间配置监控系统。测试过程中一旦某台测试机出现状况,测试白做了是不可避免的,关键是有时候你还不知道哪台测试机出问题了(比如cpu爆了,内存不够了,网路出了问题等等)。当你拿到了一些很不可思议的测试结果时内心一定是崩溃的….
3.如果团队希望能够做到持续测试,也就是在每一个版本发布过程中都能够有性能测试覆盖,维护一整套测试环境并保证它在每次自动化测试过程中都能正常工作也是必不可少的工作。这往往比重新搭建一套新的测试环境更让人头疼,比如隔壁老王有天突然手头紧偷偷借走了一台测试机。
4.性能测试不像功能性测试,比较容易对测试结果进行分析。比如Unit Test,或者接口测试,只要验证点写的没问题,对就是对,错就是错,没啥可说的。而性能测试却不是非黑即白的,首先性能指标有很多,要统筹的去看待这些结果综合分析才能给出有意义的结论。即使发现有明显问题,想定位问题也是很考验测试人员的功力的。在和很多团队聊天过程中经常听到他们说,每次大版本发布能做一次比较完整的性能测试就不错了,还持续集成?那还不得累死….
把性能测试包含在持续集成流水线中真的很难么?也不尽然。当一个技术团队满足一些基本前提条件,然后设定相对合理和明确的目标,再结合工具的支撑,这件事情就没那么困难了。
前提条件—标准化的测试环境自动部署:有稳定的产品持续部署能力。当一个技术团队还没有一个比较稳定的持续集成框架来实现持续部署的时候,考虑引入性能测试是不太现实的。毕竟我们做性能测试的前提是有一个可持续部署的被测系统。这是一个比较理想的被测系统环境:
这里有3类环境:
模块级测试环境:我们在这个阶段的测试目的是测试模块层面的接口性能,保证模块单接口更新或者新增后性能没有问题。这个环境可以不是一个完整的系统,只包含模块级别开发团队负责的模块,但是一定是一个可运行可测试的环境。这个层面的性能测试更关注模块层面的接口性能测试,环境部署规模一般是单节点小规模。
集成测试环境:我们在这个阶段的测试目的是测试系统集成环境的整体性能。如果被测系统是一个分布式,可扩展的架构,在这个环境中可以是单节点或者是少量的分布式环境。但是一定要保证这个环境是个基本完整的系统,这样我们才能端到端的测试系统性能。
准生产环境:这个环节基本是模拟生产环境的配置和规模,有的公司甚至可以用此环境和生产环境进行切换来进行系统升级。在这个环境上的性能测试主要是模拟生产环境规模的压力,以保证系统上线后能够满足真实业务的需求。
当我们能够自动的部署上述环境,或者其中某几个环境的时候,我们就有了进行性能测试的基础。
自动部署的意义不光是自动的准备被测环境,更重要的是能够准备标准化的被测环境。对于性能测试来讲,标准化的环境意义非常大,不管是被测系统硬件配置(操作系统,cpu,内存),被测软件的配置,网络配置还是系统拓扑结构,这些在每一次测试的时候都需要保持统一,或者变更可追踪。否则,作为性能测试来讲,每次环境都不一样,压力测试也就没有标准可言。
性能测试持续集成的目标与原则:在持续集成和的自动化测试中我们需要明确几个原则:第一,自动化测试的目的更多的是为了回归测试。也就是要保证系统在更新过程中无论是功能还是性能没有回退。第二,测试结果要尽量保证准确易读。如果自动化测试用例积累的越累越多,测试频率越来越快之后,往往一次测试会生成大量的测试结果。如果测试结果不准确或者不易解读,会造成测试后需要花费大量时间去分析,团队效率会大打折扣。
基于以上原则,对于性能测试来讲,我们就需要在测试前对每一个测试用例设定好性能基线。性能基线可以通过前期的手动性能测试探索得出。无论是单一的接口压测还是复杂的组合压测,流程压测,我们都可以通过测试在标准的环境上找到一个合理的基线。性能基线可以包含一下指标:测试并发数,平均响应时间,最大响应时间,平均吞吐量,被测系统CPU使用率,CPU
load,内存使用量等。当我们有了对被测系统有了这些基线后,我们就可以将测试脚本放入自动化的流程中。在每一次的测试完成后,我们只需要对比本次的测试结果和性能基线就能清晰明确的知道系统有没有性能上的回退。每次测试结束后我们的关注点可以聚焦到那些没有达到性能基线的测试用例中,定位到相关的代码或者系统配置变更,找到问题。
我们需要依照以下流程将测试用例与基线放入自动化流程中:1.编写性能测试脚本 2.对标准系统进行压测一方面调试脚本,一方面建立新用例的性能基线。不同阶段的测试环境基线是不同的。3.定义测试套件,将测试脚本组合成不同的测试套件,便于在不同环境中调用不同的套件进行测试。对于不同测试套件的理解,我们可以举个例子:比如在模块测试环境,我们会定义和模块接口相关的性能测试用例组合成套件执行。由于模块更新快,测试频率也会相对比较高,所以不宜将全部性能测试脚本都跑一遍。而在集成环境和准生产环境,我们可以定义测试用例更全面的测试套件以保证测试覆盖率。4.将性能测试脚本,套件和相应环境的基线可以放到测试平台和版本控制系统(如git,svn等)中以便在后面的自动化测试过程中自动化的调用。
工具平台支撑:对于性能测试的持续集成,我们需要有以下能力的工具和平台的支撑才能够完成。
1.测试环境能够自动生成。测试过程中不同的测试用例对并发数的要求是不同的,我们需要有一个可伸缩的测试工具来满足不同测试用例的并发需求。对于大并发量测试的系统,往往我们需要使用多台压力机同时提供压力,搭建测试集群不可避免。XMeter作为性能测试平台,无论是公有云服务还是企业私有部署版,都能够自动为不同的测试压力自动创建压力机集群,分配测试脚本执行测试,并能够实时的收集测试数据生成测试报告。而且XMeter为每台压力机都配备了性能监控,也就是说我们在测试过程中可以同时监控我们的压力机是否处于正常状态,以及时发现由于压力机本身的性能问题造成测试数据的偏差。
2.测试环境易于维护。对于一个需要长期运行的持续集成环境,测试环境也是需要长期运行和维护的,如果此环境需要大量人力去维护对生产效率提升也是重大的阻碍。XMeter作为一个成熟的性能测试平台可以很好的满足此需求。对于使用公有云线上服务的客户,用户本身完全不需要去关心平台的维护,只需要在需要测试的时候调用服务,就像使用自来水一样随用随取,简单方便。对于不能够使用公用云服务进行内网压测的客户,也可以使用企业私有部署版本,在自己的环境中搭建XMeter平台。XMeter提供了简单方便的管理员界面,可以轻松的将压力机注册到平台中。在测试过程中测试服务会自动寻找可用的压力机进行测试,测试完成后资源自动回收,实现了最大限度的资源利用率。
3.测试工具与持续集成,持续部署平台的对接。在持续集成,持续部署环境下,性能测试的触发和结果的收集应该是可以自动化的。自动化测试的触发可以为手动触发,或者是自动化环境部署完成后自动触发。这样我们就需要测试工具平台提供可自动调用的接口来满足这一需要。XMeter提供了丰富的RestfulAPI和命令行工具,可以轻松的和不同持续部署,持续集成系统对接。通过自动化的接口调用来上传脚本,启动测试和收集结果。
下面是一个以Jenkins为持续集成流水线引擎,SVN为版本控制系统,XMeter为性能测试平台的自动化测试框架图:
当然,我们也有其他的替代方案,这里只是举一个例子给大家作为参考。
到此我们简单介绍了一下如何在项目中规划和实施性能测试的持续集成。当然在实际过程中,我们还有很多细节问题需要解决。俗话说方法总是比困难多,当我们有了足够的驱动力,相对成熟的持续部署环境,明确的目标和工具支持,这些问题都可以迎刃而解。
|