1 问题
测试环境是指为了完成软件测试工作所必需的计算机硬件、软件、网络设备、历史数据等的总称,即够支持完成测试工作所需要的软件和硬件。测试环境是测试活动的基础,正确模拟生产环境,稳定支持测试活动是测试环境的基本要求。稳定可控的测试环境能够提升测试工程师的测试工作效率,测试工程师无需花费过多的时间维护测试环境的稳定、测试数据的合理等工作上。测试工程师只需正确执行测试用例(这里既包含了自动化测试用例也包含手工测试用例)就可以稳定复现测试过程。
但是在实际工作中,测试环境却是阻塞测试工作的最为主要问题,测试团队往往会在测试环境是否需要完全复制生产环境而产生争论,同时测试环境的不稳定,测试环境依赖的不确定等问题都给测试环境的搭建造成了困扰。本文给出了一些测试环境的搭建原则以及管理实践,从而最大限度的解决了如上的一些测试环境面临的种种问题。
2 测试环境的建设原则和方法
2.1 测试环境的困局
最理想的测试环境是生产环境完全复制,但是这种理想的测试环境无论是在物理机时期,还是虚拟机时期,乃至现在容器化之下都是很难做到的,难以实现生产环境的完全复制的根本原是成本。在物理机时期,生产环境往往需要部署很多台服务器部,测试环境要想完全按照生产环境建设就需要提供和生产环境一样数量级的硬件成本,这个成本问题几乎是所有团队都难以应付的,因此物理机时期,测试环境的搭建一直是一个难题。
在进入虚拟机时期以后,虽然通过虚拟化可以将一台物理机虚拟成几台服务器使用,但是一台物理机也就可以支持为数不多的几台虚拟机,所以投入的成本问题依旧制约着测试环境的建设规模。那么随着技术的发展,容器化的出现改变了物理机时期、虚拟机时期的一个主要问题,一台物理机可以支持成百上千个容器运行,从而大大提高了物理机的利用率,降低了成本。
容器有着绝对优势,这些优势让测试环境完全复制生产系统成为可能,但是在微服务架构盛行的今天,就算用廉价的容器完全复制生产环境也是需要很高的成本的。因此测试环境应该如何建设也是一个急需解决的问题。
2.2 功能测试环境的搭建原则
功能测试主要是根据产品特性、操作描述和用户方案,测试一个产品的特性和可操作行为以确定它们是否满足设计需求。因此功能测试的测试环境就应该满足如下原则:
- 1. 基础设施尽最大可能做到相同
这里的基础设施包含了网络拓扑结构、防火墙配置、负载均衡策略等。网络拓扑结构相似,这里的网络拓扑结构指内网环境,不包含互联网的部分。
防火墙配置要做到完全一致,众所周知很多生产故障都是因为防火墙配置问题导致的,但是在实际测试中,很多测试环境中都没有配置防火墙,导致防火墙配置部分的问题没有被测试到,因此在功能测试环境中要求必须和生产环境完全一样的防火墙配置,以确保通过功能测试验证每一个业务请求都是通过防火墙返回了正确的响应。
负载均衡策略要完全一致,这里是因为负载均衡会导致各式各样的“共享”问题,例如权限共享、数据共享等,因此在功能测试的时候如果测试环境的负载均衡策略和生产一致,对应问题也就被覆盖到了。
- 2. 操作系统要和生产环境完全一致
操作系统是一个系统能够对外提供服务的基础,那么我们更希望在功能测试的时候能够兼顾任何系统和操作系统之间的依赖关系,因此在功能测试环境中的操作系统在版本、补丁、配置等方面要和生产环境完全一致。
- 3. 支持被测服务的公共服务要完全一致
这里所说的是一些web容器、消息中间件等在配置上、版本上要和生产环境完全一致,这样才能保证所有的公共服务在测试环境都被验证过。
- 4. 测试数据要在一个完全已知道状态并且要可控制
在测试环境中,测试数据是一个动态过程状态,因此对于功能测试的数据初始化需要有其分钟级的备份机制,可以随时恢复到任意一个已备份的初始状态。同时,在每次功能测试开始之前,测试数据都是处于一个已知并且可控的状态,这样才能保证测试用例执行后的测试结果是稳定的、可信的。
2.3 性能测试环境的搭建原则
性能测试对测试环境的要求更加苛刻,测试工程师不能随意搭建一个测试环境,然后线性评估生产环境的性能结果。性能测试环境在功能测试环境的搭建原则之上,还推荐使用计算单元的方式。那么什么是计算单元呢?假设服务A需要对外提供服务,需要服务入口网页Portal,服务A1、服务A2,那么通过不断地性能测试来划分一个计算单元包含一个服务A、2个服务A1、4个服务A2能够达到最优秀的性能配比,如下图
上图就是一个计算单元示意图,这个组合刚好在提供100并发的情况下,响应时间、CPU利用率、内存利用率、吞吐量、内网带宽占用量等都满足需求且都是最优数据。那么在系统上线后,出现并发急剧增加的情况下,可以同步建立一个计算单元,从而达到快速的最优比扩容,这样也快速提升了整体技术解决方案的吞吐量。
3 测试环境的管理
测试环境建设原则是测试环境如何创建的问题,测试环境如何维护和管理是测试环境面临的另外一个难题。当测试环境建设完成后,伴随着被测试系统复杂度的升高,制品团队规模的增大,测试环境的需求也会变得复杂,测试环境如何管理就变成了一个必须解决的问题。测试环境的管理也应该针对不同的测试类型而有不同的处理方式,如果永远都以优先级作为唯一的判断标准,测试环境会永远成为研发效能环境的瓶颈点。本文通过设计主干测试环境以及变更分支接入的方法,解决了容器化下的测试环境管理混乱、测试环境紧缺的问题。
主干环境和分支环境可以满足一个微服务多个并行需求的场景,其中主干环境是最接近生产环境的测试环境,对外主要承担了联调测试的支持职责,当变更在生产环境正式发布后,会同步更新主干环境对应的微服务节点。当有对应微服务发生变更的需求需要验证时,在启动新变更的服务后,在服务网关上讲服务的调用方和依赖方的链接入口修改成新变更的微服务就可以开始测试了。在完成测试后,在服务网关上恢复调用链路,等制品发布生产环境成功后,再用新变更服务替换原有服务。
制品团队的本次变更需要修改B服务和C服务,那么制品团队构建了变更后的服务B1和服务C1,然后通过服务网关将服务入口A的访问入口从服务B调整到服务B1,这样测试数据就会流经分支环境服务B1和服务C1,然后C1 调用服务D返回主干环境,当完成测试后,恢复主干环境的调用关系,发布B和C服务的变更到生产环境,当生产环境发布成功后,测试主干环境和生产环境就出现了服务B和服务C上的不一致,因此替换测试主干环境服务B和服务C为原来的服务B1和服务C1,完成变更全流程,同时可以保持生产环境和主干环境的误差均会在分钟范围内追平。
4 总结
测试环境是测试工作的基础,如果在测试过程中需要不断的维护测试环境的正确性才能保证测试工作的正常秩执行,那么测试工作的效率会严重受到影响。基于上述原则建设测试环境,可以帮助测试工程师聚焦于测试工作本身,从而实现更高效的质量保障工作。