This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,190 @@
<audio id="audio" title="39 | 从小作坊到工厂什么是Selenium Grid如何搭建Selenium Grid" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/f2/3b/f2518c17ede48c1e11261138ebe6243b.mp3"></audio>
你好我是茹炳晟今天我分享的主题是“从小作坊到工厂什么是Selenium Grid如何搭建Selenium Grid”。
从今天开始我们就要一起进入测试基础架构这个新的系列了。我将用四篇文章的篇幅从0到1为你深入剖析大型互联网企业的测试基础架构设计以及其原始驱动力和你探讨测试执行环境设计、测试报告平台设计以及测试基础架构与CI/CD的集成等内容。当然在这其中还会涉及到很多具有前瞻性的设计创新。
虽说测试基础架构是资深测试开发人员的必备技能,但此时你可能还并不清楚测试基础架构到底指的是什么?没关系,当你阅读完这个系列的文章之后,相信你一定可以对测试基础架构,以及其关键设计有一个清晰、全面的认识。
所以,今天我就先和你分享一下,我眼中的测试基础架构到底是指什么?
## 什么是测试基础架构?
测试基础架构指的是,执行测试的过程中用到的所有基础硬件设施以及相关的软件设施。因此,我们也把测试基础架构称之为广义的测试执行环境。通常来讲,测试基础架构主要包括以下内容:
- 执行测试的机器;
- 测试用例代码仓库;
- 发起测试执行的Jenkins Job
- 统一的测试执行平台;
- 测试用例执行过程中依赖的测试服务,比如提供测试数据的统一测试数据平台、提供测试全局配置的配置服务、生成测试报告的服务等;
-
**由于测试基础架构的核心是围绕测试执行展开的,所以我们今天就先来重点讨论一下“执行测试的机器”部分。**
这部分内容的展开我会从早期最简单的方法谈起然后探讨这个方法在实际执行中的弊端并由此引出我们今天讨论的主角Selenium Grid。
先试想一下你要在一个典型测试场景中基于某种浏览器去执行Web应用的GUI测试。这时你首先要做的就是找到相应的机器并确保上面已经安装了所需的浏览器。如果这台机器上还没有安装所需浏览器的话你需要先安装这个浏览器。一切准备就绪后你就可以使用这台机器执行测试了。
如果你要执行的测试只需要覆盖一种浏览器的话,那就很简单了,你只要事先准备好一批专门的机器或者虚拟机,然后安装好所需的浏览器就可以了。同时,如果测试用例的数量也不是很多的话,你需要的这批机器或者虚拟机的数量也不会很多。执行测试时,你只要将需要使用的那台机器的地址提供给测试用例就可以了。
其实这种模式就是典型的“小作坊”模式。“小作坊”模式的特点就是人工维护一批数量不多通常在30台以内的执行测试的机器然后按需使用。
对于小团队来讲,“小作坊”模式的问题并不大。但是,随着测试覆盖率要求的提升,以及测试用例数量的增加,这种“小作坊”模式的弊端就逐渐显现,并被不断放大了。其中,最主要问题体现在以下四个方面:
<li>
当Web应用需要进行不同浏览器的兼容性测试时首先你需要准备很多台机器或者虚拟机并安装所需的不同浏览器然后你要为这些机器建立一个列表用于记录各台机器安装了什么浏览器最后你在执行测试时需要先查看机器列表以选择合适的测试执行机。
</li>
<li>
当Web应用需要进行同一浏览器的不同版本的兼容性测试时你同样需要准备很多安装有同一浏览器的不同版本的测试执行机并为这些机器建立列表记录各台机器安装的浏览器版本号然后执行测试时先查看列表以选择合适的测试执行机。
</li>
<li>
测试执行机的机器名或者IP发生变化以及需要新增或者减少测试机时都需要人工维护这些机器列表。很显然这种维护方式效率低下且容易出错。
</li>
<li>
在GUI自动化测试用例的数量比较多的情况下你不希望只用一台测试执行机以串行的方式执行测试用例而是希望可以用上所有可用的测试执行机以并发的方式执行测试用例以加快测试速度。为了达到这个目的你还是需要人工管理这些测试用例和测试执行机的对应关系。
</li>
**这四种情况的问题,可以归结为:测试执行机与测试用例的关系是不透明的,即每个测试用例都需要人为设置测试执行机。**
为了改善这种局面Selenium Grid就应运而生了。
- 一方面使用Selenium Grid可以让测试机器的选择变得“透明”。也就是说我们只要在执行测试用例时指定需要的浏览器版本即可而无需关心如何找到合适的测试执行机。因为这寻找符合要求的测试执行机的工作Selenium Grid可以帮你完成。
- 另一方面Selenium Grid的架构特点天生就能很好地支持测试用例的并发执行。
接下来我就和你详细聊聊到底什么是Selenium GridSelenium Grid的架构是什么样的。
<img src="https://static001.geekbang.org/resource/image/30/bf/3077a24abcd93f063c7510fb81ccf9bf.png" alt="" />
从本质上讲Selenium Grid是一种可以并发执行GUI测试用例的测试执行机的集群环境采用的是HUB和Node模式。这个概念有些晦涩难懂我来举个例子吧。
假如,现在有个律师事务所要接受外来业务,那么就会有一个老大专门负责对外接受任务。收到任务后,这个老大会根据任务的具体要求找到合适的手下,然后将该任务分发给手下去执行。
那么,这个老大是怎么知道哪个手下最适合处理这个任务呢?其实,这个老大手下的每个人都会事先报备自己具备的技能,这样老大在分发任务的时候,就可以做到“有的放矢”了。
现在我们再回到Selenium Grid。Selenium Grid由两部分构成一部分是Selenium Hub另一部分是Selenium Node。
将这个律师事务所的例子与Selenium Grid做个类比它们的对应关系是
- 这个对外的老大对应的是Selenium Hub
- 具体执行任务的手下对应的是Selenium Node
- 老大接到任务后分配给手下执行的过程就是Selenium Hub将测试分配到Selenium Node执行的过程
- 老大的手下向他报备自己技能的过程就是Selenium Node向Selenium Hub注册的过程。
也就是说,**Selenium Hub用来管理各个Selenium Node的注册信息和状态信息并且接收远程客户端代码的测试调用请求并把请求命令转发给符合要求的Selenium Node执行。**
现在我们已经搞明白了什么是Selenium Grid以及Selenium Grid的工作模式。Selenium Grid的功能是不是很酷炫呢那么Selenium Grid的搭建是不是很难接下来我们就看看如何搭建自己的Selenium Grid吧。
在这里我会依次给你介绍传统的Selenium Grid和基于Docker的Selenium Grid的搭建方法。通过这部分内容我要达到的目的是可以帮你搭建起属于自己的Selenium Grid。
## 传统Selenium Grid的搭建方法
我将通过一个实例和你分享如何搭建一个传统的Selenium Grid。
现在我们的需求是搭建一个具有1个Node的Selenium Grid。那么通常来讲我们需要2台机器其中一台作为Hub另外一台作为Node并要求这两台机器已经具备了Java执行环境。
<li>
通过官网下载selenium-server-standalone-<version>.jar文件。这里需要注意的是不管是Hub还是Node都使用同一个JAR包启动只是启动参数不同而已。
</li>
<li>
将下载的selenium-server-standalone-<version>.jar文件分别复制到两台机器上。
</li>
<li>
选定其中一台机器作为Selenium Hub并在这台机器的命令行中执行以下命令
</li>
```
java -jar selenium-server-standalone-&lt;version&gt;.jar -role hub
```
在这条命令中,“-role hub”的作用是将该机器启动为Selenium Hub。启动完成后这台机器默认对外提供服务的端口是4444。
然后,你就可以在这台机器上通过[http://localhost:4444/grid/console](http://localhost:4444/grid/console)观察Selenium Hub的状态也可以在其他机器上通过http://&lt;Hub_IP&gt;:4444/grid/console观察Selenium Hub的状态。其中&lt;Hub_IP&gt;是这台Selenium Hub机器的IP地址。由于此时还没有Node注册到该Hub上所以你看不到任何的Node信息。
启动过程和状态信息分别如图2、3所示。
<img src="https://static001.geekbang.org/resource/image/a2/98/a275424067255c72da249734a203ba98.png" alt="" />
<img src="https://static001.geekbang.org/resource/image/3d/15/3d73539d2b14aa45d4f2b19334eb9a15.png" alt="" />
1. 在另一台作为Selenium Node的机器上执行以下命令
```
java -jar selenium-server-standalone-&lt;version&gt;.jar -role node -hub http:// &lt;Hub_IP&gt;:4444/grid/register
```
这条命令中,“-role node”的作用是将该机器启动为Selenium Node并且通过“-hub”指定了Selenium Hub的节点注册URL。
执行成功后你可以再次打开http://&lt;Hub_IP&gt;:4444/grid/console观察Selenium Hub的状态。此时你可以看到已经有一个Node挂载到了Hub上。这个Node就是用来实际执行测试的机器了。并且这个Node上已经缺省提供了5个Firefox浏览器的实例、5个Chrome浏览器的实例和1个IE浏览器的实例同时默认允许的并发测试用例数是5个。
如果你想自己配置这些内容可以在启动Node的时候提供不同的启动参数。具体可以指定哪些参数你可以参考[Selenium Grid](https://github.com/SeleniumHQ/selenium/wiki/Grid2)的官方文档。
如图4所示为Node的启动过程如图5所示为在Hub端注册Node的过程如图6所示为挂载完Node后Selenium Hub的状态。
<img src="https://static001.geekbang.org/resource/image/db/96/db5edbf3d119ac17710a9640d905c596.png" alt="" />
<img src="https://static001.geekbang.org/resource/image/3e/4b/3e4133f06d2cc5d812cef1f8f375c74b.png" alt="" />
<img src="https://static001.geekbang.org/resource/image/58/06/58bf48cb7af0db82546902a3a5c99406.png" alt="" />
1. 完成上述操作后在测试用例中通过以下代码将测试指向Selenium Hub然后由Selenium Hub完成实际测试执行机的分配与调度工作。其中最关键的部分是创建RemoteWebDriver实例的第一个参数这个参数不再是一个具体的测试执行机的IP地址或者名字了而是Selenium Hub的地址。
```
DesiredCapabilities capability = DesiredCapabilities.firefox();
WebDriver driver = new RemoteWebDriver(new URL(&quot;http://&lt;Hub_IP&gt;:4444/wd/hub&quot;), capability);
```
至此我们就已经完成了Selenium Grid的搭建工作。正如上面的五个步骤所示这个搭建过程非常简单。接下来你就自己动手尝试一下吧。
## 基于Docker的Selenium Grid的搭建方法
目前Docker技术的广泛普及再加上它的轻量级、灵活性等诸多优点使得很多软件都出现了Docker版本。当然Selenium Grid也不例外。所以我也会在这里和你简单介绍一下基于Docker的Selenium Grid搭建过程。
在这个搭建过程中你将会发现基于Docker运行Selenium Grid的话机器的利用率会得到大幅提高。因为一台实体机或者虚拟机往往可以运行非常多的Docker实例数量而且Docker实例的启动速度也很快。因此相对于虚拟机或者实体机方案而言Docker方案可以更高效地创建Node。
接下来我们就一起看看如何基于Docker来搭建Selenium Grid吧。
在基于Docker搭建Selenium Grid之前你需要先安装Docker环境。具体安装方法你可以参考[Docker的官方文](https://docs.docker.com/get-started/)[](https://docs.docker.com/get-started/)。
接下来你就可以通过以下命令分别启动Selenium Hub和Selenium Node了。
```
#创建了Docker的网络grid
$ docker network create grid
#以Docker容器的方式启动Selenium Hub并且对外暴露了4444端口
$ docker run -d -p 4444:4444 --net grid --name selenium-hub selenium/hub:3.14.0-europium
#以Docker容器的方式启动并挂载了Chrome的Selenium Node
$ docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-chrome:3.14.0-europium
#以Docker容器的方式启动并挂载了Firefox的Selenium Node
$ docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-firefox:3.14.0-europium
```
相比基于实体机或者虚拟机搭建Selenium Grid的方法基于Docker的方式灵活性更大、启动效率也更高、可维护性也更好。而且在更高级的应用中比如当我们需要根据测试用例的排队情况动态增加Selenium Grid中的Node数量的时候Docker都将是最好的选择。关于这部分内容具体的细节我会在后面两篇文章中详细展开。
## 总结
今天我从测试基础架构的概念讲起并和你分享了传统Selenium Grid 和基于Docker的Selenium Grid的搭建方法。
首先,测试基础架构指的是,执行测试的过程中用到的所有基础硬件设施以及相关的软件设施,包括了执行测试的机器、测试用例代码仓库、统一的测试执行平台等。而,今天我针对测试执行的机器这个主题展开了分享。
在最早起的测试执行场景中采用的方法是由人工维护一批数量不多通常在30台以内的执行测试的机器然后按需使用完成整个测试过程这也是典型的“小作坊”模式。随着测试需求日益复杂“小作坊”模式的缺点也暴露无疑其中最主要的问题在于测试执行机和测试用例的对应关系不“透明”以及由此带来的测试用例并发执行难以实施的问题。
于是为了解决这个问题就出现了Selenium Grid。简单地说Selenium Grid就是一种可以并发执行GUI测试用例的测试执行机的集群环境。由于它采用的是Hub和Node的架构模式所以很容易就解决了“小作坊”模式的测试用例与测试执行机间的不“透明”关系以及测试用例并发执行的问题。
而Selenium Grid的搭建也是非常简单。其中传统Selenium Grid搭建时只要在理解了Selenium Grid架构之后通过Java命令分别启动Hub和Node即可而基于Docker的Selenium Grid在搭建时就更简单了直接通过Docker命令运行已经封装好的Image就可以了。
这么来看Selenium Grid功能强大搭建方法更是简单也因此已经广泛应用于测试执行环境的搭建中。
## 思考题
目前Selenium Grid已经有Docker的版本了你有没有考虑过可以在云端比如PCF、GCP、AWS上搭建Selenium Grid呢在我看来这将是未来的主流方案你也是类似的看法吗
感谢你的收听,欢迎你给我留言。

View File

@@ -0,0 +1,129 @@
<audio id="audio" title="40 | 从小工到专家:聊聊测试执行环境的架构设计(上)" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/b5/97/b506a52199f802152675a8bc6381eb97.mp3"></audio>
你好,我是茹炳晟,今天我和你分享的主题是“从小工到专家:聊聊测试执行环境的架构设计(上)”。
在上一篇文章中我介绍了Selenium Grid的基础知识以及如何搭建Selenium Grid。现在你已经非常清楚Selenium Grid的作用主要是承担了测试执行机器的角色被用来执行实际的测试工作。但是实际工程中的测试执行环境往往更复杂而测试执行机器也只是其中的一个重要部分。
因此我们还需要控制发起测试的Jenkins并管理测试用例执行和结果显示的系统。同时为了更方便地与CI/CD流水线集成我们还希望不同类型的测试发起过程可以有统一的接口。
那么,从今天开始的两篇文章,我将由浅入深地和你聊聊测试执行环境中的基本概念,以及架构设计的思路。
## 什么是测试执行环境?
测试执行环境的定义有广义和狭义之分:
- 狭义的测试执行环境,单单指测试执行的机器或者集群。比如,我在上一篇文章[《从小作坊到工厂什么是Selenium Grid如何搭建Selenium Grid](https://time.geekbang.org/column/article/40468)中介绍的Selenium Grid就是一个最经典的测试执行集群环境。
- 广义的测试执行环境,除了包含具体执行测试的测试执行机以外,还包括测试执行的机器或者集群的创建与维护、测试执行集群的容量规划、测试发起的控制、测试用例的组织以及测试用例的版本控制等等。
因此,**广义的测试执行环境也被称为测试基础架构。而,我在测试基础架构这个系列里,要和你讨论的是广义上的测试执行环境。也就是说,我会和你重点讨论测试基础架构的概念和设计。**
如果你是在一些小型的软件公司做测试工程师的话,可能并没有听说过“测试基础架构”这个概念,或者也只是停留在对其的一知半解上。但,实际情况是,无论小型的软件公司还是中大型的软件公司都存在测试基础架构。
只是,在小型的软件公司,由于自动化测试的执行量相对较小,测试形式也相对单一,所以测试执行架构非常简单,可能只需要几台固定的专门用于测试执行的机器就可以了。那么,此时测试基础架构的表现形式就是测试执行环境。
而对于中大型的软件公司,尤其是大型的全球化电商企业,由于需要执行的自动化测试用例数量非常多,再加上测试本身的多样性需求,测试基础架构的设计是否高效和稳定将直接影响产品是否可以快速迭代、发布上线。因此,中大型的软件公司都会在测试基础架构上有比较大的投入。
一般情况下,中大型企业在测试基础架构上的投入,主要是为了解决以下这几方面的问题:
- **简化测试的执行过程**。我们不用每次执行测试时,都必须先去准备测试执行机,因为测试执行机的获取就像日常获取水电一样方便了。
- **最大化测试执行机器的资源利用率**,使得大量的测试执行机可以以服务的形式为公司层面的各个项目团队提供测试执行的能力。
- **提供大量测试用例的并发执行能力**,使得我们可以在有限的时间内执行更多的测试用例。
- **提供测试用例的版本控制机制**,使得测试执行的时候可以根据实际被测系统的软件版本自动选择对应的测试用例版本。
- **提供友好的用户界面**,便于测试的统一管理、执行与结果展示。
- **提供了与CI/CD流水线的统一集成机制**从而可以很方便地在CI/CD流水线中发起测试调用。
以此类推,如果你想要设计出高效的测试基础架构,就必须要从以下几个方面着手:
**对使用者而言,测试基础架构的“透明性”**。也就是说,测试基础架构的使用者,无需知道测试基础架构的内部设计细节,只要知道如何使用就行。
我在上一篇文章中和你探讨的Selenium Grid就是一个很好的案例。实际使用Selenium Grid时你只需要知道Hub的地址以及测试用例对操作系统和浏览器的要求就可以而无需关注Selenium Grid到底有哪些Node以及各个Node又是如何维护的技术细节。
**对维护者而言,测试基础架构的“易维护性”**。对于一些大型的测试而言你需要维护的测试执行机的数量会相当大比如Selenium的Node的数量达到成百上千台后如果遇到WebDriver升级、浏览器升级、病毒软件升级的情况时如何高效地管理数量庞大的测试执行机将会成为一大挑战。
所以早期基于物理机和虚拟机时这个执行机的管理问题就非常严重。但是出现了基于Docker的方案后这些问题都因为Docker容器的技术优势而被轻松解决了。
**对大量测试用例的执行而言,测试基础架构执行能力的“可扩展性”**。这里的可扩展性指的是,测试执行集群的规模可以随着测试用例的数量自动扩容或者收缩。
以Selenium Gird为例可扩展性就是Node的数量和类型可以根据测试用例的数量和类型进行自动调整。这里建议你先记住这个概念我还会在专栏的后续文章中详细展开。
**随着移动App的普及测试基础架构中的测试执行机需要支持移动终端和模拟器的测试执行**。目前很多的商业云测平台已经可以支持各种手机终端的测试执行了。其后台实现基本都是采用的Appium + OpenSTF + Selenium Gird的方案。
很多中小企业,因为技术水平以及研发成本的限制,一般直接使用这类商业解决方案。但是,对于大型企业来说,出于安全性和可控制性的考量,一般会选择自己搭建移动测试执行环境。
理解了什么是测试执行环境后,我们再一起看看测试基础架构的设计吧。
但是,这里我需要说明的是,我并不会以目前业界的最佳实践为例,和你讨论应该如何设计测试基础架构。
为什么呢?因为这样做,虽然看似可以简单粗暴地解决实际问题,但是这中间涉及到的琐碎问题,将会淹没测试基础架构设计的主线,反而会让你更加困惑为什么我要这么做,而不能那么做。
因此,本着“知其所以然”的原则,我还是会以遇到问题然后解决问题的思路,由浅入深地从最早期的测试基础架构说起,带你一起去经历一次测试基础架构设计思路的演进。在我看来,这样的思路,才是深入理解一门技术的有效途径,也希望你可以借此将测试基础架构的关键问题吃得更透。
## 早期的测试基础架构
早期的测试基础架构会将测试用例存储在代码仓库中然后是用Jenkins Job来Pull代码并完成测试的发起工作。如图1所示。
<img src="https://static001.geekbang.org/resource/image/f2/ba/f20e2df431199038d25e9cabcacc31ba.png" alt="" />
在这种架构下,自动化测试用例的开发和执行流程,是按照以下步骤执行的:
<li>
**自动化测试开发人员在本地机器开发和调试测试用例**。这个开发和调试过程通常是测试开发人员自己的工作电脑上进行。也就是说他们在开发完测试用例后会在本机执行测试用例。这些测试用例会在本机打开指定的浏览器并访问被测网站的URL然后发起业务操作完成自动化测试。
</li>
<li>
**将开发的测试用例代码Push到代码仓库**。如果自动化测试脚本在测试开发人员本地的电脑上顺利执行完成那么接下来我们就会将测试用例的代码Push到代码仓库至此标志着自动化测试用例的开发工作已经完成。
</li>
<li>
<p>**在Jenkins中建立一个Job用于发起测试的执行**。这个Jenkins Job的主要工作是先从测试用例代码仓库中Pull测试用例代码并发起构建操作然后在远端或者本地固定的测试执行机上发起测试用例的执行。<br />
这个Jenkins Job通常会将一些会发生变化的参数作为Job自身的输入参数。比如远端或者本地固定的测试执行机的IP地址或者名字再比如被测系统有多套环境需要指定被测系统的具体名字等。</p>
</li>
这种测试架构,对于测试用例数量不多、被测系统软件版本不太复杂的场景的测试需求,基本都可以满足。但在实际使用时,你总会感觉哪里不太方便。
比如每次通过Jenkins Job发起测试时你都需要填写测试用例需要在哪台测试执行机上执行。而此时这台测试执行机是否处于可用状态是否正在被其他测试用例占用都是不可知的那么你就需要在测试发起前进行人为确认或者开发一个执行机器环境检查的脚本帮你确认。并且当远端测试执行机的IP或者名字有变化时或者当远端测试执行机的数量有变动时你都需要能提前获知这些信息。
所以,这些局限性,也就决定了这种架构只能适用于小型项目。
说到这里你可能已经想到了不是有Selenium Grid吗我完全可以用Selenium Gird代替固定的测试执行机。没错这就是测试基础架构的第一次的重大演进也因此形成了目前已经被广泛使用的经典测试基础架构。
## 经典的测试基础架构
用Selenium Grid代替早期测试基础架构中的“远端或本地固定的测试执行机器”就形成了经典的测试基础架构。其架构如图2所示。
<img src="https://static001.geekbang.org/resource/image/8e/8c/8e9da1055a174071903c785fcabdf78c.png" alt="" />
这样你在每次发起测试时就不再需要指定具体的测试执行机器了只要提供固定的Selenium Hub地址就行然后Selenium Hub就会自动帮你选择合适的测试执行机。
同时由于Selenium Grid中Node的数量可以按需添加所以整体的测试执行任务比较重时你就可以增加Grid中Node的数量。
另外Selenium还支持测试用例的并发执行可以有效缩短整体的测试执行时间。
所以这种基于Selenium Grid的经典测试基础架构已经被大量企业广泛采用。
但是随着测试用例数量的继续增加传统的Selenium Grid方案在集群扩容、集群Node维护等方面遇到了瓶颈并且Jenkins Job也因为测试用例的增加变得臃肿不堪。因此变革经典的测试基础架构的呼声也越来越高。
为此业界考虑将Selenium Grid迁移到Docker并且提供便于Jenkins Job管理的统一测试执行平台。这也是我将在下一篇文章中要和你继续讨论的话题。
拭目以待吧。
## 总结
从广义上讲,测试执行环境除了包括测试执行机以外,还包括测试执行机的维护、集群的容量规划、测试发起的控制、测试用例的组织以及测试用例的版本控制等等。这也就是我要和你的测试基础架构的定义。
从定义上,我们也可以看出在设计一个高效的测试基础架构,应该从这几个方面着手:
- 保证对使用者的“透明性”;
- 需要具备对维护者而言的“易维护性”;
- 做到对大量测试用例并发执行的“可扩展性”;
- 兼顾移动App对测试执行环境的需求。
然后我以遇到问题然后解决问题的思路和你分享了早期的测试基础架构向经典的测试基础架构的演进。这个演变可以归纳为用Selenium Grid代替早期测试基础架构中的“远端或本地固定的测试执行机器”打破了因为需要人为指定并维护测试执行机而只能适用于小型测试项目的局限性从而形成了已被广泛使用的经典测试基础架构。
而经典的测试基础架构在测试用例持续增加时也会面临诸如集群扩容、Jenkins Job臃肿不堪等等问题于是基于Docker的测试基础架构便应运而生了。
## 思考题
你所在的团队是否在使用Selenium Grid在实际使用过程中你是否有遇到过什么瓶颈又是如何解决的呢
感谢你的收听,欢迎你给我留言一起讨论。

View File

@@ -0,0 +1,149 @@
<audio id="audio" title="41 | 从小工到专家:聊聊测试执行环境的架构设计(下)" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/9c/fc/9ce44d3ac8471b3f08c6295824d043fc.mp3"></audio>
你好,我是茹炳晟,今天我和你分享的主题是“从小工到专家:聊聊测试执行环境的架构设计(下)”。
在上一篇文章中我介绍了测试基础架构的概念以及早期的和经典的两种测试基础架构。在文章的最后我提到经典的测试基础架构中采用的Selenium Grid方案在测试用例的数量持续增加的情况下会带来集群扩容、Jenkins Job臃肿不堪等诸多问题因此我们考虑将Selenium Grid迁移到Docker并且提供便于Jenkins Job管理的统一测试执行平台。
所以,今天的这篇文章,我就会围绕这些瓶颈以及对应的解决方案来展开。
## 基于Docker实现的Selenium Grid测试基础架构
随着测试基础架构的广泛使用以及大量的浏览器兼容性测试的需求Selenium Grid中Node的数量会变得越来越大也就是说我们需要维护的Selenium Node会越来越多。
在Node数量只有几十台的时候通过人工的方式去升级WebDriver、更新杀毒软件、升级浏览器版本可能还不是什么大问题。但是当需要维护的Node数量达到几百台甚至几千台的时候这些Node的维护工作量就会直线上升。虽然你可以通过传统的运维脚本管理这些Node但维护的成本依然居高不下。
同时随着测试用例数量的持续增长Selenium Node的数量也必然会不断增长这时安装部署新Node的工作量也会难以想象。因为每台Node无论是采用实体机还是虚拟机都会牵涉到安装操作系统、浏览器、Java环境以及Selenium。
而目前流行的Docker容器技术由于具有更快速的交付和部署能力、更高效的资源利用以及更简单的更新维护能力也就使得Docker相比于传统虚拟机而言更加得“轻量级”。
因此,**为了降低Selenium Node的维护成本我们自然而然地想到了目前主流的容器技术也就是使用Docker代替原本的虚拟机方案。**
基于Docker的Selenium Grid可以从三个方面降低我们维护成本
<li>
由于Docker的更新维护更简单使得我们只要维护不同浏览器的不同镜像文件即可而无需为每台机器安装或者升级各种软件
</li>
<li>
Docker轻量级的特点使得Node的启动和挂载所需时间大幅减少直接由原来的分钟级降到了秒级
</li>
<li>
Docker高效的资源利用使得同样的硬件资源可以支持更多的Node。也就是说我们可以在不额外投入硬件资源的情况下扩大Selenium Grid的并发执行能力。
</li>
因此现在很多大型互联网企业的测试执行环境都在向Docker过渡。
而具体如何基于Docker搭建一套Selenium Grid你可以参考我在第39篇文章[《从小作坊到工厂什么是Selenium Grid如何搭建Selenium Grid](https://time.geekbang.org/column/article/40468)中介绍的方法。由此可见将原本基于实体机或者虚拟机实现的Selenium Grid改进成为基于Docker实现的过程也很简单、灵活。
如图1所示就是一个基于Docker实现的Selenium Grid的测试基础架构。
<img src="https://static001.geekbang.org/resource/image/56/75/56142f87923aa3c2e27746b91e2c0f75.png" alt="" />
## 引入统一测试执行平台的测试基础架构
在实际的使用过程中基于Docker的Selenium Grid使得测试基础架构的并发测试能力不断增强也因此会有大量项目的大量测试用例会运行在这样的测试基础架构之上。
当项目数量不多我们可以直接通过手工配置Jenkins Job并直接使用这些Job控制测试的发起和执行。但是当项目数量非常多之后测试用例的数量也会非常多这时新的问题又来了
<li>
管理和配置这些Jenkins Job的工作量会被不断放大
</li>
<li>
这些Jenkins Job的命名规范、配置规范等也很难实现统一管理从而导致Jenkins中出现了大量重复和不规范的Job
</li>
<li>
当需要发起测试或者新建某些测试用例时都要直接操作Jenkins Job。而这个过程对于不了解这些Jenkins Job细节的人比如新员工、项目经理、产品经理来说这种偏技术型的界面体验就相当不友好了。
</li>
为此我们为了管理和执行这些发起测试的Jenkins Job实现了一个GUI界面系统。在这个系统中我们可以基于通俗易懂的界面操作完成Jenkins Job的创建、修改和调用并且可以管理Jenkins Job的执行日志以及测试报告。
这,其实就是统一测试执行平台的雏形了。
有了这个测试执行平台的雏形后,我们逐渐发现可以在这个平台上做更多的功能扩展,于是这个平台就逐渐演变成了测试执行的统一入口。
在这里,我列举了这个平台两个最主要的功能和创新设计,希望可以给你以及你所在公司的测试基础架构建设带来一些启发性的思考。
**第一,测试用例的版本化管理**。我们都知道,应用的开发有版本控制机制,即:每次提测、发布都有对应的版本号。所以,为了使测试用例同样可追溯,也就是希望不同版本的开发代码都能有与之对应的测试用例,很多大型企业或者大型项目都会引入测试用例的版本化管理。最简单直接的做法就是,采用和开发一致的版本号。
比如被测应用的版本是1.0.1那么测试用例的版本也命名为1.0.1。在这种情况下当被测应用版本升级到1.0.2的时候我们会直接生成一个1.0.2版本的测试用例而不应该直接修改1.0.1版本的测试用例。
这样当被测环境部署的应用版本是1.0.1的时候我们就选择1.0.1版本的测试用例而当被测环境部署的应用版本是1.0.2的时候我们就相应地选择1.0.2版本的测试用例。
所以,我们就在这个统一的测试执行平台中,引入了这种形式的测试用例版本控制机制,直接根据被测应用的版本自动选择对应的测试用例版本。
**第二提供基于Restful API的测试执行接口供CI/CD使用**。这样做的原因是测试执行平台的用户不仅仅是测试工程师以及相关的产品经理、项目经理很多时候CI/CD流水线才是主力用户。因为在CI/CD流水线中每个阶段都会有不同的发起测试执行的需求。
我们将测试基础架构与CI/CD流水线集成的早期实现方案是直接在CI/CD流水线的脚本中硬编码发起测试的命令行。这种方式最大的缺点在于灵活性差
- 当硬编码的命令行发生变化或者引入了新的命令行参数的时候CI/CD流水线的脚本也要一起跟着修改
- 当引入了新的测试框架时发起测试的命令行也是全新的那么CI/CD流水线的脚本也必须被一起改动。
因此为了解决耦合性的问题我们在这个统一的测试执行平台上提供了基于Restful API的测试执行接口。任何时候你都可以通过一个标准的Restful API发起测试CI/CD流水线的脚本也无须再知道发起测试的命令行的具体细节了只要调用统一的Restful API即可。
如图2所示就是引入了统一测试执行平台的测试基础架构。
<img src="https://static001.geekbang.org/resource/image/40/43/40be3cb1a925bbcf24c2a710f0711443.png" alt="" />
## 基于Jenkins集群的测试基础架构
这个引入了统一测试执行平台的测试基础架构看似已经很完美了。但是随着测试需求的继续增长又涌现出了新的问题单个Jenkins成了整个测试基础架构的瓶颈节点。因为来自于统一测试执行平台的大量测试请求会在Jenkins上排队等待执行而后端真正执行测试用例的Selenium Grid中很多Node处于空闲状态。
为此将测试基础架构中的单个Jenkins扩展为Jenkins集群的方案就势在必行了。如图3所示就是基于Jenkins集群的测试基础架构。
<img src="https://static001.geekbang.org/resource/image/db/f5/db974bd10bf6146c2ad1afbdb310ccf5.png" alt="" />
因为Jenkins集群中包含了多个可以一起工作的Jenkins Slave所以大量测试请求排队的现象就再也不会出现了。
而这个升级到Jenkins集群的过程中对于Jenkins集群中Slave的数量到底多少才合适并没有定论。一般的做法是根据测试高峰时段Jenkins中的排队数量来预估一个值。通常最开始的时候我们会使用4个Slave节点然后观察高峰时段的排队情况如果还是有大量排队就继续增加Slave节点。
## 测试负载自适应的测试基础架构
引入了Jenkins集群后整个测试基础架构已经很成熟了基本上可以满足绝大多数的测试场景了。但是还有一个问题一直没有得到解决那就是Selenium Grid中Node的数量到底多少才合适
- 如果Node数量少了那么当集中发起测试的时候就会由于Node不够用而造成测试用例的排队等待这种场景在互联网企业中很常见
- 而如果Node数量多了虽然可以解决测试高峰时段的性能瓶颈问题但是又会造成空闲时段的计算资源浪费问题。当测试基础架构搭建在按使用付费的云端时计算资源的浪费就是资金浪费了。
为了解决这种测试负载不均衡的问题Selenium Grid的自动扩容和收缩技术就应运而生了。
Selenium Grid的自动扩容和收缩技术的核心思想是通过单位时间内的测试用例数量以及期望执行完所有测试的时间来动态计算得到所需的Node类型和数量然后再基于Docker容器快速添加新的Node到Selenium Grid中而空闲时段则去监控哪些Node在指定时间长短内没有被使用并动态地回收这些Node以释放系统资源。
通常情况下几百乃至上千台Node的扩容都可以在几分钟内完成Node的销毁与回收的速度同样非常快。
至此测试基础架构已经演变得很先进了基本可以满足大型电商的测试执行需求了。测试负载自适应的测试基础架构具体如图4所示。
<img src="https://static001.geekbang.org/resource/image/da/a4/daeb20ac9fee266ecbabbfadfa2305a4.png" alt="" />
## 如何选择适合自己的测试基础架构?
现在,我已经介绍完了测试基础架构的演进,以及其中各阶段主要的架构设计思路,那么对于企业来说,应当如何选择最适合自己的测试基础架构呢?
其实,对于测试基础架构的建设,我们切忌不要为了追求新技术而使用新技术,而是应该根据企业目前在测试执行环境上的痛点,来有针对性地选择与定制测试基础架构。
比如你所在的企业如果规模不是很大测试用例执行的总数量相对较少而且短期内也不会有大变化的情况那么你的测试基础架构完全就可以采用经典的测试基础架构而没必要引入Docker和动态扩容等技术。
再比如如果是大型企业测试用例数量庞大同时还会存在发布时段大量测试请求集中到来的情况那么此时就不得不采用Selenium Gird动态扩容的架构了。而一旦要使用动态扩容那么势必你的Node就必须做到Docker容器化否则无法完全发挥自动扩容的优势。
所以说,采用什么样的测试基础架构不是由技术本身决定的,而是由测试需求推动的。
## 总结
在今天这篇文章中,我从测试基础架构演进的视角,和你分享了测试基础架构发展的前世今生。
首先为了降低测试用例过多时Selenium Grid的维护成本我们用Docker容器代替了经典测试基础架构中的实体机/虚拟机形成了基于Docker实现的Selenium Grid测试基础架构。
而后我们发现测试用例的数量达到一定规模后管理和执行发起测试的Jenkins Job成了问题。于是我们引入了一个基于GUI界面的测试执行平台并在其上扩展了诸如测试用例版本化、提供基于Restful API的测试执行接口等功能。从而形成了由这个统一测试执行平台发起测试的测试基础架构形态。
而为了进一步解决由单个Jenkins带来的系统瓶颈问题我们过渡到了基于Jenkins集群的测试基础架构通过多个同时工作的Jenkins Slave解决了大量测试请求排队的问题。
随后为了解决Selenium Grid中Node的数量到底多少才合适的问题我和你谈论了创新设计的Selenium Grid的自动扩容和收缩技术。至此测试负载自适应的测试基础架构也终于“千呼万唤始出来”了。
最后,我谈论了不同企业该如何选择最适合自己的测试基础架构的问题。这里,我强调了一定要根据测试需求选择测试基础架构,而不能一味地追求最新的技术。
我希望通过这种授人以渔的方式,可以帮你拓宽思路,并将测试基础架构的设计思路、思想,运用到你的实际工作中去。
## 思考题
其实,在我讲述的这个测试基础架构的设计和搭建过程中,还有很多可以优化和创新的点。你觉得哪些部分可以再优化呢?你还有哪些想法呢?
欢迎你给我留言,我们一起讨论。

View File

@@ -0,0 +1,146 @@
<audio id="audio" title="42 | 实战:大型全球化电商的测试基础架构设计" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/d5/b0/d5a6e6737e1c124481bc29c23400ceb0.mp3"></audio>
你好,我是茹炳晟。今天我和你分享的主题是“实战:大型全球化电商的测试基础架构设计”。
在前面的两篇文章中我和你分享了测试基础架构的设计以及演进之路其中涉及到了统一测试执行平台、Selenium Grid和Jenkins等一系列的概念。
在掌握了这些基础内容之后,今天我就和你一起看看大型全球化电商的测试基础架构又是如何设计的。这其中除了我之前介绍过的概念以外,还会引入一些新的服务和理念,我都会和你一一道来。
因为我们已经掌握了测试基础架构设计的基础知识,所以今天我会采用一种不同于以往由浅入深的方式,直接给出大型全球化电商网站的全局测试基础架构的最佳实践,然后再依次解释各个模块的主要功能以及实现基本原理。
其实,**大型全球化电商网站全局测试基础架构的设计思路,可以总结为“测试服务化”**。也就是说,测试过程中需要用的任何功能都通过服务的形式提供,每类服务完成一类特定功能,这些服务可以采用最适合自己的技术栈,独立开发,独立部署。而至于到底需要哪些测试服务,则是在理解了测试基础架构的内涵后再高度抽象后得到的。从本质上来看,这种设计思想其实和微服务不谋而合。
根据在大型全球化电商网站工作的实际经验我把一个理想中的测试基础架构概括为了一张图如图1所示
<img src="https://static001.geekbang.org/resource/image/d9/71/d9456825d8e9568e9453efe5207fb571.png" alt="" />
这个理想的测试基础架构包括了6种不同的测试服务分别是统一测试执行服务、统一测试数据服务、全局测试配置服务、测试报告服务、测试执行环境准备服务以及被测系统部署服务。
接下来我们一起看看这6大测试服务具体是什么以及如何实现。
## 统一测试执行服务
从本质上看统一测试执行服务其实和统一测试执行平台你可以再回顾一下第41篇文章[《从小工到专家:聊聊测试执行环境的架构设计(下)》](https://time.geekbang.org/column/article/40915)是一个概念。只不过统一测试执行服务强调的是服务也就是强调测试执行的发起是通过Restful API调用完成的。
总结来说以Restful API的形式对外提供测试执行服务的方式兼具了测试版本管理、Jenkins测试Job管理以及测试执行结果管理的能力。
统一测试执行服务的主要原理是通过Spring Boot框架提供Restful API内部实现是通过调度Jenkins Job具体发起测试。如果你对此还有疑惑请参考第40篇文章[《从小工到专家:聊聊测试执行环境的架构设计(上)》](https://time.geekbang.org/column/article/40582)。
还记得我在前面一直提到的将测试发起与CI/CD流水线集成吗这个统一测试执行服务采用的Restful API调用主要用户就是CI/CD流水线脚本。我们可以在这些脚本中通过统一的Restful API接口发起测试。
## 统一测试数据服务
统一测试数据服务其实就是统一测试数据平台你也可以再回顾一下第37篇[《测试数据的“银弹”- 统一测试数据平台(上)》](https://time.geekbang.org/column/article/40156)和第38篇[《测试数据的“银弹”- 统一测试数据平台(下)》](https://time.geekbang.org/column/article/40166)文章的内容)。
任何测试但凡需要准备测试数据的都可以通过Restful API调用统一测试数据服务然后由它在被测系统中实际创建或者搜索符合要求的测试数据。而具体的测试数据创建或者搜索的细节对于测试数据的使用者来说是不需要知道的。也就是说统一测试数据服务会帮助我们隐藏测试数据准备的所有相关细节。
同时,在统一测试数据服务内部,通常会引入自己的内部数据库管理测试元数据,并提供诸如有效测试数据数量自动补全、测试数据质量监控等高级功能。
在实际工程项目中测试数据的创建通常都是通过调用测试数据准备函数完成的。而这些函数内部主要通过API和数据库操作相结合的方式实际创建测试数据。
如果你对测试数据的准备还有疑问或者想知道更多的细节内容可以再回顾一下前面“测试数据准备”的系列的第35~38篇文章。
## 测试执行环境准备服务
测试执行环境准备服务其实我也已经介绍过了。这里“测试执行环境”是狭义的概念特指具体执行测试的测试执行机器集群对于GUI自动化测试来说指的就是Selenium Grid对于API测试来说指的就是实际发起API调用的测试执行机器集群。
测试执行环境准备服务的使用方式,一般有两种:
- 一种是由统一测试执行服务根据测试负载情况主动调用测试执行环境准备服务来完成测试执行机的准备比如启动并挂载更多的Node到Selenium Grid中
- 另一种是,测试执行环境准备服务不直接和统一测试执行服务打交道,而是由它自己根据测试负载来动态计算测试集群的规模,并完成测试执行集群的扩容与收缩。
## 被测系统部署服务
被测系统部署服务主要被用来安装部署被测系统和软件。虽然这部分内容我以前没有提到过但它很好理解。其实现原理是调用DevOps团队的软件安装和部署脚本。
- 对于那些可以直接用命名行安装和部署的软件来说很简单,一般只需要把人工安装步骤的命名行组织成脚本文件,并加入必要的日志输出和错误处理即可。
- 对于那些通过图形界面安装的软件一般需要找出静默Silent模式的安装方式然后通过命令行安装。
如果被测软件安装包本身不支持静默安装模式我强烈建议给发布工程师提需求要求他加入对静默安装模式的支持。其实一般的打包工具都能很方能地支持Silent安装模式并不会增加额外的工作量。
被测系统部署服务一般由CI/CD流水线脚本来调用。在没有被测系统部署服务之前CI/CD流水线脚本中一般会直接调用软件安装和部署脚本。而在引入了被测系统部署服务后我们就可以在CI/CD流水线脚本中直接以Restful API的形式调用标准化的被测系统部署服务了。这样做的好处是可以实现CI/CD流水线脚本和具体的安装部署脚本解耦。
## 测试报告服务
测试报告服务,也是测试基础架构的重要组成部分,其主要作用是为测试提供详细的报告。
测试报告服务的实现原理,和传统测试报告的区别较大。
传统的软件测试报告通常直接由测试框架产生比如TestNG执行完成后的测试报告以及HttpRunner执行结束后的测试报告等等也就是说测试报告和测试框架绑定在了一起。
对于大型电商网站而言,由于各个阶段都会有不同类型的测试,所以测试框架本身就具有多样性,因此对应的测试报告也是多种多样。而测试报告服务的设计初衷,就是希望可以统一管理这些格式各异、形式多样的测试报告,同时希望可以从这些测试报告中提炼出面向管理层的统计数据。
为此测试报告服务的实现中引入了一个NoSQL数据库用于存储结构各异的测试报告元数据。在实际项目中我们会改造每个需要使用测试报告服务的测试框架使其在完成测执行后将测试报告的元数据存入到测试报告服务的NoSQL数据库。这样我们再需要访问测试报告的时候就可以直接从测试报告服务中提取了。
同时由于各种测试报告的元数据都存在了这个NoSQL数据库中所以我们就可以开发一些用于分析统计的SQL脚本帮助我们获得质量相关信息的统计数据。
测试报告服务的主要使用者是测试工程师和统一测试执行服务。对统一测试执行服务来说,它会调用测试报告服务获取测试报告,并将其与测试执行记录绑定,然后进行显示。而测试工程师则可以通过测试报告服务这个单一的入口,来获取想要的测试报告。
## 全局测试配置服务
全局测试配置服务是这6个服务中最难理解的部分其本质是要解决测试配置和测试代码的耦合问题。这个概念有点抽象我们一起看个实例吧。
大型全球化的电商网站在全球很多国家都有站点,这些站点的基本功能是相同的,只是某些小的功能点会有地域差异(比如,因当地法务、政策等不同而引起的差异;又比如,由货币符号、时间格式等导致的细微差异)。
假设我们在测试过程中需要设计一个getCurrencyCode函数来获取货币符号那么这个函数中就势必会有很多if-else语句以根据不同国家返回不同的货币符号。
比如如图2所示的“Before”代码中就有4个条件分支如果当前国家是德国isDESite或者法国isFRSite那么货币符号就应该是“EUR” 如果当前国家是英国isUKSite那么货币符号就应该是“GBP”如果当前国家是美国isUSSite或者是墨西哥isMXSite那么货币符号就应该是“USD”如果当前国家不在上述的范围那么就抛出异常。
<img src="https://static001.geekbang.org/resource/image/af/46/af8414d9a311fd5b40e0d3b0abf84746.png" alt="" />
上述函数的逻辑实现本身并没有问题但是当你需要添加新的国家和新的货币符号时就需要添加更多的if-else分支当国家数量较多的时候代码的分支也会很多。更糟糕的是当添加新的国家时你会发现有很多地方的代码都要加入分支处理十分不方便。
那么,有什么好的办法,可以做到在添加新的国家支持时,不用改动代码吗?
其实,仔细想来,**之所以要处理这么多分支,无非是因为不同的国家需要不同的配置值**(这个实例中,不同国家需要的不同配置值就是货币符号),那如果我们可以把配置值从代码中抽离出去放到单独的配置文件中,然后代码通过读取配置文件的方式来动态获取配置值,这样就可以做到加入新的国家时,不用再修改代码本身,而只要加入一份新国家的配置文件就可以了。
为此我们就有了如图2所示的“After”代码以及图中右上角的配置文件。“After”代码的实现逻辑是通过GlobalRegistry并结合当前环境的国家信息来读取对应国家配置文件中的值。比如GlobalEnvironment.getCountry()的返回值是“US”也就是说当前环境的国家是美国那么GlobalRegistry就会去“US”的配置文件中读取配置值。
这样实现的好处是假定某天我们需要增加日本的时候getCurrencyCode函数本身不用做任何修改而只需要增加一个“日本”的配置文件即可。
至此我们已经一起了解了大型全球化电商网站的全局测试基础架构设计以及其中的6个主要测试服务的作用及其实现思路。现在我再和你分享一个实例看看这样的测试基础架构是如何工作的帮助你进一步理解测试基础架构的本质。
## 大型全球化电商网站测试基础架构的使用实例
这个实例我会以CI/CD作为整个流程的起点。因为在实际工程项目中自动化测试的发起与执行请求一般都是来自于CI/CD流水线脚本。
**首先CI/CD流水线脚本会以异步或者同步的方式调用被测系统部署服务**安装部署被测软件的正确版本。这里被测系统部署服务会访问对应软件安装包的存储位置并将安装包下载到被测环境中然后调用对应的部署脚本完成被测软件的安装。之后CI/CD脚本中会启动被测软件并验证新安装的软件是否可以正常启动如果这些都没问题的话被测系统部署服务就完成了任务。
这里需要注意的是:
- 如果之前的CI/CD脚本是以同步方式调用的被测系统部署服务那么只有当部署、启动和验证全部通过后被测系统部署服务才会返回然后CI/CD脚本才能继续执行
- 如果之前的CI/CD脚本是以异步方式调用的被测系统部署服务那么被测系统部署服务会立即返回然后等部署、启动和验证全部通过后才会以回调的形式通知CI/CD脚本。因此CI/CD脚本也要为此做特殊处理。
**被测系统部署完成后CI/CD脚本就会调用统一测试执行服务**。统一测试执行服务会根据之前部署的被测软件版本选择对应的测试用例版本然后从代码仓库中下载测试用例的Jar包。
**接下来,统一测试执行服务会将测试用例的数量、浏览器的要求,以及需要执行完成的时间作为参数,调用测试执行环境准备服务。**
测试执行环境准备服务会根据传过来的参数动态计算所需的Node类型和数量然后根据计算结果动态加载更多的基于Docker的Selenium Node到测试执行集群中。此时动态Node加载是基于轻量级的Docker技术实现的所以Node的启动与挂载速度都非常快。
因此,统一测试执行服务通常以同步的方式调用测试执行环境准备服务。
测试执行环境准备好之后统一测试执行服务就会通过Jenkins Job发起测试的执行。**测试用例执行过程中,会依赖统一测试数据服务来准备测试需要用到的数据,并通过全局测试配置服务获取测试相关的配置与参数。**
同时,**在测试执行结束后,还会自动将测试报告以及测试报告的元数据发送给测试报告服务进行统一管理。**
以上就是这套测试基础架构的执行过程了。
## 总结
通过前面几篇文章,我们已经掌握了测试基础架构的基础知识,所以今天我分享的主题就是,从实战的角度帮你夯实测试基础架构的基础。
其实大型全球化电商网站全局测试基础架构的设计思路可以总结为“测试服务化”。于是我总结了一个比较理想的测试基础架构应该包括6大服务统一测试执行服务、统一测试数据服务、全局测试配置服务、测试报告服务、测试执行环境准备服务以及被测系统部署服务。
其中,统一测试执行服务,本质上讲就是统一测试执行平台;统一测试数据服务,其实就是统一测试数据平台;测试执行环境准备服务,指的是狭义的测试执行环境准备。这几部分内容,我都已经在前面的文章中分享过了,如果你有任何问题,也可以再给我留言一起讨论。
而被测系统部署服务主要是被用来安装部署被测系统和软件这部分也很简单测试报告服务虽然和传统的测试报告区别较大但也可以通过引入一个NoSQL数据库以存储的测试报告元数据的方式去实现。
全局测试配置服务是这6个服务中最难理解的部分其本质是要解决测试配置和测试代码的耦合问题。我通过一个具体的不同国家对应不同货币符号的例子和你讲述了具体如何解耦。
## 思考题
除了我今天分享的6大服务以外其实还有更多的服务可以帮助我们提升测试效能比如全局Mock服务、工程效能工具链仓库等等。你还能想到有哪些与测试相关的服务吗
感谢你的收听,欢迎你给我留言一起讨论。