08 | 测试环境要多少?从现实需求说起

在整个持续交付生命周期中,测试环境的易用程度会直接影响软件的交付速度,但因为以下两点,它又是最被容易忽略的一环。

  1. 我们总是把环境理想化,忽略了其管理的难度;

  2. 我们也很少设立专职的环境管理员,导致环境长期处于混乱状态。

通常,我们在项目初期并不会关注测试环境的问题,然而在回顾时却发现在环境问题上浪费的时间非常惊人:硬件资源申请困难,测试环境配置繁琐,测试应用更新困难,基础设施稳定性差,服务调用异常,多项目并行造成互相干扰等等问题。

而不管你是开发人员还是测试人员,相信你都或多或少地碰到过这些问题。

在接下来的《环境管理》系列文章中,我会和你聊聊构建一整套好的测试环境的关键点以及具体实施方案。今天,我就先跟你说说和测试环境相关的两个问题:

  1. 测试环境的结构一般是怎样的?

  2. 什么才是好的测试环境?

互联网公司测试环境的结构

当公司规模较小时,测试环境的维护相对容易。开发和测试共用一套数据库缓存等基础设施,因为应用数量不多,开发环境可以是单机的,无论是手动或半自动化的更新测试环境的应用,花费的时间都还在可接受范围内。

这时,公司环境的结构很简单,分为开发环境,测试环境,生产环境即可。

但实际上,我看到的大多数公司的研发过程及配套环境并没有这么简单,一般都会存在5套以上的大环境以及更多的子环境,每个环境的机器数量可能有数十台甚至更多。

那么为什么会需要这么多套环境呢?我把主要原因概括为了以下两个方面。

  1. 纵向上看,人员的增多提高了项目的并行度,如果这时还使用一套环境的话,就会发生以下问题:

    • 开发同学在debug一个困难问题时,发现下游的应用突然就不可用了;
    • 测试同学在跑了10多分钟测试脚本后,发现应用已经被开发更新掉了。
      这样的体验是让人崩溃的。
  2. 横向上看,公司的应用架构逐渐转为微服务化,完整的应用数量很容易就达到了几百甚至几千个的量级,建立一套独立而完整的环境变得越来越复杂,往往是研发团队想要构建一套新的环境却构建不出来。

所以,目前互联网公司常见的环境模型一般分为开发环境,功能测试环境,验收测试环境,预发布环境,生产环境这五个大套环境。

第一,开发环境

微服务架构下,单机已经无法完整地运行业务应用,这就需要开发环境内包含一套完整的业务应用依赖以及相关的基础设施,以保证业务开发同学能在本地完成开发测试。

第二,功能测试环境

在开发环境下,每个下游依赖应用都只有一个可用的stable版本。而在实际的开发过程中,由于项目的并行开发,往往会同时存在多个可依赖的版本。而每个项目组的同学在测试时,都希望测试过程中的关键依赖应用是可以被独占的,版本是固定的,不会被其他项目组干扰。

所以,一套独立的功能测试环境就很有必要了。通常,互联网企业会通过中间件的方式分割出一块隔离区域,在功能测试环境中创建多个子环境来解决这个问题。

第三,验收测试环境

验收测试环境和功能测试环境是完全隔离的。当功能测试通过后,你可以在验收测试环境进行最终的验收。

它除了可以用作测试之外,还可以用作产品展示。所以,除了测试和开发人员,产品经理也是验收测试环境的主要使用者。

第四,预发布环境

到了预发布阶段,应用已经进入了生产网络,和真实的生产应用共享同一套数据库等基础设施。预发布是正式发布前的最后一次测试,在这个环境中往往可以发现线下环境中发现不了的Bug。这个环境的运维标准等同于生产环境,一般不允许开发人员直接登录机器。

根据不同的业务需求和部署策略,不同公司对预发布环境的实现也有所不同:

  • 一种比较常见的方式是,将金丝雀发布作为预发布,从接入真实流量的集群中挑选一台或一小组机器先进行版本更新,通过手工测试以及自动化测试和监控系统验证,降低新版本发布的风险。
  • 另一种做法是,独立出一组始终不接入真实流量的机器,调用在预发布环境中形成闭环。

相对于第一种方式,第二种方式对生产环境的影响更小,但需要额外的资源和维护成本。

第五,生产环境

生产环境是用户真实使用的环境,对安全性和稳定性的要求最高。

什么是好的测试环境?

在和你分享什么是好的测试环境前,建议你先思考一下开发环境、功能测试环境、验收测试环境、预发布环境这四种测试环境形成的原因是什么,这样有利于你更好的理解好的测试环境的含义。

首先,搭建测试环境的目的是保证最终交付的软件质量,但每套测试环境的用户并不完全一样:

  1. 开发环境的用户是开发同学;

  2. 功能测试环境的主要用户是测试同学;

  3. 验收测试环境的用户是产品经理和测试同学;

  4. 预发布环境的使用者是测试同学,但收益者却是运维同学。

而每种角色对于产品研发流程中的需求也是不同的:

  1. 开发同学关注研发效率;

  2. 测试同学关注测试的可靠性;

  3. 产品经理更关注的是真实的用户体验和产品的完整性;

  4. 预发布环境的需求其实来自于运维同学,他们需要保证生产环境的稳定性,减少生产环境的变更,所以需要将预发布环境与线下环境完全隔离。

如果你是一位测试环境治理工程师,在规划测试环境以及开发和实施工具的时候,最关键的就是要考虑到不同环境的主要用户是谁,环境要做成什么样才能满足用户在研发流程中的需求。当用户不用发愁环境问题时,研发效率也就自然而然地上去了。

当然,不论一套环境用户是测试同学还是开发同学,以下几个需求都是必须被做到的。

  1. 可得性,即在开发一个新项目时,能快速获取构建一个环境需要的机器,基础设施。最好的情况是,能随时可得,随时归还。

  2. 快速部署,即在搭建新环境时,能以最快的速度构建出一整套完整的环境。测试环境的部署很频繁,在代码提交后,能在很短的时间内构建代码,在环境上更新,就能更早开始测试。

  3. 独立性,即一个环境在使用过程中,可以不受其他项目测试人员的干扰。

  4. 稳定性,即不会因为下游服务,基础设施的异常,造成测试中断、等待。

  5. 高仿真,主要分为两个方面:“测试数据真实”,即能在测试环境构建出真实的测试用例;“环境真实”,即基础服务的架构和行为与线上环境保持一致,避免因为环境不一致造成测试结果不一致。

但是,毕竟各个环境的用户和使用场景不同,它们的需求也是有差别的。 比如,相对于开发环境,验收测试环境对测试数据的仿真性要求会更高,而开发环境的灵活性,决定了不会过于严格的维护测试数据的真实性。

所以,如何评价一个好的测试环境,就是看它是否最终满足了核心使用者的需求。

总结

通常,互联网公司的环境会包括:开发环境、功能测试环境、验收测试环境、预发布环境和生产环境这5套。

测试环境的目的是要保证最终将交付的软件产品的质量,所以好用的测试环境,不能从规模、性能和作用的角度来评判,而应该是从它能否满足用户需求去保证软件质量的角度进行定义,于是得出:

当一个环境可以满足其真正核心用户的需求时, 就是一个好用的测试环境。

除此之外,你还需要理解,环境是昂贵的,不仅涉及单一的机器资源成本,环境副本数的增加也意味着更难管理,更复杂的流程,所以仅仅考虑单套使用者的体验是不够的。

那么,在我的下一篇文章中,将会分享多环境带来的成本问题,以及如何在成本、效率、可管理之间权衡取舍。

思考题

  1. 请你思考一下测试环境中最让你痛苦的一点是什么?

  2. 如果让你来优化测试环境, 你会如何去改善这最让你痛苦的一点?

欢迎你给我留言。

精选留言

  • 齐涛-道长

    2018-07-22 12:04:35

    最痛苦的是防火墙问题。公司只有一套Jenkins在生产环境网段,公司策略又不允许生产环境访问测试环境,于是乎目前还遗留的仅能访问的个别测试机器极其宝贵,后续一旦这些机器被换掉,那就真是完全隔离了。另外公司的网络策略现在限制不允许开22端口,于是乎我可以预见到不远的未来我们将从Jenkins自动化部署转变为全部自己动手部署了
    作者回复

    你提的问题很好,我也确实忘了这一块的内容。其实比较好的网络划分是为持续交付或部署系统之类的工具划分出专用的工具网段,此网段可同时访问测试和生产,反之则是受控的。虽然从网络管理角度来说会复杂一些,但结构和用途就更清晰了

    2018-07-22 16:33:11

  • Xiangjun

    2018-07-21 12:37:21

    如何利用开源红利,快速搭建一套持续交付平台。
    在这一部分,我会手把手地,带你真正去搭建一套最小集合的持续交付平台。

    什么时候讲干货?
    作者回复

    哈哈,其实那些只是“知其然”,还是要看“知其所以然”的带问号的几讲呢

    2018-07-22 16:27:49

  • pein

    2018-07-23 00:06:18

    感觉讲的比较皮毛,问题提的很尖锐,比如多个开发团队并行开发的话环境怎么保证,但是说的方案只是五个串行环境的方案,并不能解决之前作者提出的问题,还是希望作者可以多讲一些百度查不到的信息
    作者回复

    环境问题会有多讲,作为第一讲,力求先把问题解释清楚,后续自然会有更清晰的解答。也可以关注一下全部目录哦,定位自己特别关注的部分,毕竟读者的背景,经验都会有所不同,还是需要照顾全面:)

    2018-07-23 16:06:27

  • 卿卿

    2020-05-11 16:41:57

    “到了预发布阶段,应用已经进入了生产网络,和真实的生产应用共享同一套数据库等基础设施。”

    如果涉及到数据库变更,某些情况下回与当前生产环境冲突应该如何解决?一直觉得数据库的变更才是持续交付的难点所在。
    作者回复

    需要避免类似冲突的情况,数据和代码逻辑都可以做一些兼容,还可以利用开关

    2020-06-09 08:35:02

  • 戴斌

    2020-03-20 17:39:59

    最痛苦的是测试环境太多,当前有8个测试环境,维护痛苦。并行开发的时候为了避免影响测试环境较多,还有部分转为性能、自动化等做的测试环境。
    去年我们将测试环境都转到容器化平台,做了自动打包测试发布等工作,现环境维护与之前服务器的方式简便了很多,另外资源池更丰富,可以快速的部署测试环境。
  • 王保安

    2019-08-02 10:26:29

    请问老师:预生产环境也是连接生产环境的数据库吧,那发布预发环境的时候,需要执行SQL,岂不是影响了生成环境。这个问题怎么解决呢。
  • 不需往后看

    2018-07-22 00:10:54

    都是干货,支持老师。

    之前自己摸索过持续集成/交付相关的思路,分支策略和测试环境是重中之重,没有分治策略和测试环境,持续集成根本无从谈起。

    希望没太有耐心的那几位同学,认真看看之前的内容,相信对后面课程的学习会有很大帮助。
  • 怀揣梦想的学渣

    2023-05-04 17:14:08

    看完这篇文章,我有些理解为何docker那么火,它让大家可以快捷复用有限的物理机。
  • 花灰

    2021-07-23 11:40:51

    最痛苦的是机器资源有限,每启用一套新环境都需要暂用新的资源,导致经常机器告警,所以环境中很多依赖服务如何做到既能公用但是又互不影响呢?

    当然是可以通过加机器来解决这个问题,但是公司不会有预算无限量加机器的
  • 小寞子。(≥3≤)

    2021-02-26 18:56:34

    问题问得太好了。 现实中 在云计算的发展 还有serverless下 。导致环境变得越来越复杂。 还有一些企业自己的古老系统 很难有多个不同环境的system of record, 还有不同团队不同的速度。 如何协调。 不同的成熟度。 。 微服务下一个软件可能包含一大堆不同的repo。 不用container的话 很难搞
  • Tom

    2020-03-17 17:28:54

    你好,将金丝雀发布作为预发布,接入部分真实流量,产生了新版本的数据。如果线上版本系统读到新版本数据,比如线上版本系统支持某个选项值范围是1和2,新版本产生数据3,线上版本可能出现非预期效果,该如何处理这类问题呢?
  • 春之绿野

    2019-06-08 13:23:30

    环境太乱了,无数的线纠缠在一起,光看看就崩溃。
    测试工具不是跨平台的,只能windows 上运行,不能用docker做成自动化可恢复的。有了问题不能无脑重装。
    环境太脆弱了,今天这个线接触不好了明天那个接触不好了,虽然就是重新插拔,但排查费时间啊。
    没有文档,对新手比较痛苦。
  • 黄无由

    2019-04-11 16:50:18

    老师,请问回归测试在哪个环境?
  • hyeebeen

    2018-12-29 14:53:23

    比较痛苦的问题是:多套测试环境之间的同步,还有对外有第三方接口依赖的时候的联调。
  • MsgR

    2018-10-28 12:02:53

    一般我只做四套环境。每套环境都是应需求而生,统一的本地开发环境,环境与线上一致的的测试场景,使用环境和数据与线上一致的预发布环境,生产环境。按照老王的分法,我们应该是把验收测试与预发布环境合一了。
    作者回复

    环境的多少主要还是遵循研发需求,只有最适合,没有最好

    2018-10-30 17:57:30

  • 仗剑走天涯

    2018-08-03 19:30:09

    而每个项目组的同学在测试时,都希望测试过程中的关键依赖应用是可以被独占的,版本是固定的,不会被其他项目组干扰。
    这段似乎不足以说明为什么需要一套功能测试环境啊
  • jay

    2018-07-25 10:32:28

    王总,请问SaaS用微服务架构合适吗?
    作者回复

    微服务,说到底就是为了解耦,把复杂问题简单化,只要是这个目标,就是合理的了

    2018-07-27 17:29:16

  • 旭东(Frank)

    2018-07-24 09:24:14

    现在测试环境和开发环境的网络互通,经常因为开发的配置问题导致与测试的服务一起启动,造成服务被掳走到开发环境。
    作者回复

    下一讲中就会讲到解决方案

    2018-07-24 09:32:19

  • 叶子

    2018-07-23 09:07:24

    要部署这么多不同的环境,在开发资源上会不会需要投入的成本如何控制呢
    作者回复

    下一讲就会提到成本和如何做的问题

    2018-07-23 11:35:39

  • 不需往后看

    2018-07-23 09:03:29

    老师你好,对于 java 这块的自动化测试一直有个困惑 - 即,如何组织测试代码、如何管控单元测试/集成测试。

    比如单元测试和集成测试的目录结构是什么样的?

    再比如集成测试我知道通常有两种组织方式,一种是和单元测试代码放在一起,通过文件夹以及类名后缀来和单元测试区分,另一种是把集成测试独立为一个 maven 模块,但是这样会存在不同环境模块依赖问题(比如ide 下没问题,但测试环境下报依赖找不到的错误)。到底哪种组织方式更好?

    再比如单元测试和集成测试具体如何和持续集成交织在一起?这块是不是后面会讲到 🙈🙈

    希望老师能指点一二,感谢
    作者回复

    毕竟不是专门讲测试,讲不到很透,但一般我们是分开目录结构的,单元测试和集成测试将会在两个隔离环境进行,而依赖问题还是要看具体案例用标准的方式来解决,当然集成测试还要善用mock

    2018-07-23 16:18:33