大规模持续集成

今天主要说一说 k8s 对 CI 能有怎样的支持。持续集成这个话题并不陌生,基本上大多数人都参与在其中。 我做面试官的时候,几乎绝大部分候选人都会说自己做过持续集成,实际上也差不多是这样。 找个虚拟机或者实体机,用 shell 写个部署环境的脚本,在 jenkins 上配置一下 pipeline,git 上一提交代码就触发 pipeline, 单测,编译,出包,部署,自动化测试一条龙就出来了。技术上并没什么门槛,属于懂点技术的都能做的范畴,更重要的可能还是在策略和思想上。大部分还没入门的同学感觉很神秘很高大上,大部分跨过这个门的同学感觉不过如此。 这也造就了一种情况,就是当我问一些候选人关于持续集成的问题的时候, 大部分会有两种反应,一种是觉得这玩意没什么好问的,说来说去就那么几个套路。 第二种是,口若悬河把持续集成吹的上天入地,实际一问其实他的场景特别简单。

持续集的原理确实属于说的烂大街的了。 属于业界很成熟的理念,算是大家的共识。 在很久以前它还是一个很高大上的概念,但自从 jenkins 普及了以后,实现难度已经到了一个很低的程度了。 我记得几年前的时候,我也属于觉得这玩意不过如此的。 但是我记得以前有个人跟我说过,你觉得简单只是因为你面对的场景还不够复杂。 是的, 如果你只是面对一个模块或者几个模块的持续集成, 面对一套测试环境甚至只面对一套测试环境的某几个模块,那确实是简单的。 但如果你面对的是一个有几十上百个模块 (每个模块都有独立的 repo) 组成的产品, 要维护数套甚至数十套测试环境,达到每日构建次数数以千计的时候。 你就不会觉得这玩意那么简单了。 这就是我曾经和现在正在面对的情况。 所以说在持续集成中,如果按技术难度分类的话,环境治理一定是 top 1。 当你面对如此之多的构建次数和测试环境的时候,当你面一套环境这么多个模块以及这么复杂的部署架构的时候。 想用单纯的 jenkins + shell 来搞定环境基本上就是痴人说梦了。 所以才有人说想玩微服务就要先搞定部署。

K8S 带来的环境治理

尤其是大家都知道我们公司是做机器学习的,为了能够保证机器学习平台的研发和测试效率,一个能够支撑大规模测试环境的基础设施是十分必要的。为什么这么说呢?

  • 首先但凡是涉及到机器学习的业务,运行时间都非常慢。 有时候做测试的时候跑一个模型要几个小时甚至一天都是有的。也就是说,我们运行测试的成本比较高。如果在运行测试的途中环境出了什么问题那么损失还是很大的。多人共用一套环境难免会有互相踩踏的情况,例如一个 RD 在测试自己的模块,另一个人上来把服务重启了。这时候我们心里一般就是一万头某种动物飘过。所以我们一般希望能有多套环境分担这个压力。这就增加了测试环境的数量。尤其是团队越来越大的时候,测试环境的数量已经到达了一个恐怖的量级。
  • 其次如果各位所在的公司也像我们一样做 TO B 的业务,那么我们的测试环境就需要多版本管理,要有能力随时快速的搭建起特定版本的产品环境供开发,产品,测试,以及技术支持人员使用。所以这无疑又增加了环境管理设置的复杂度。
  • 再有就是随着环境数量的扩张,我们的环境从单节点走向集群,这时候我们对环境调度能力的要求会比较高,例如我们要对环境的资源进行计算和限制,保证最大化利用资源的同时不会撑爆系统。例如我们要保证系统有足够的冗余,在某些环境出现故障的时候能够自动检测出来并在冗余节点进行恢复。例如我们需要能够实现多租户管理,执行资源管控,限制超售行为. 例如我们希望系统有一定能力的无人值守运维能力等等。
  • 团队越来越庞大,引入微服务架构后对于运维和测试更是灾难级的影响。 对性能更是有着苛刻的要求,因为微服务架构下的模块数量是恐怖的,大量的研发人员提交代码触发 CI 流程,造成了每日的构建次数达到了千量的级别。随着团队的扩展,以后还会有万量级别的压力。 所以单机编译构建已经是一个不可容忍的方案。 我们需要横向扩展能力。

所以我们经过一段时间的讨论和实验,引入了 k8s+docker 来完成这个目标。首先 docker 它具有以下的优势

  • 标准化:所有环境一个镜像,解决环境差异性。避免因为开发环境和测试环境不一致带来的问题。
  • 快速化:启动时间短,秒级。
  • 隔离性:namesapce,cgroups,联合文件系统提供除内核外完整的隔离性,解决互相影响的问题。
  • 易扩展:使用镜像迅速搭建 N 套环境,无间隙。 版本管理 -- 镜像的版本管理对应测试环境的版本管理,易操作。
  • 易用性:Dockerfile 编写简单,会写 shell 的人就会制作镜像

而 k8s 也有很多的优势:

  • 天然的解决方案:玩过 k8s 的都知道,使用 k8s 你几乎可以不用太担心负载均衡,弹性伸缩,服务发现,路由转发等等令人头疼的问题。 它的 service 和 deployment 自动帮你做负载均衡,HPA 自动的弹性伸缩,kubedns 为你提供域名解析,实现服务发现。 官方的 ingress 直接为你实现好了 7 层路由。
  • 自动化运维:k8s 的自动化运维能力也是让人津津乐道的。它的健康检查能全方位的检测容器状态和进程状态。出现问题的时候自动销毁,自动修复。 容器出错重启容器,节点宕机漂移到其他可用节点重新部署。期间负载均衡模块自动导流。
  • 强大的调度能力:在 k8s 中实现多租户是很方便的。 quota 可以隔离资源,namespace 可以隔离应用。 node selector 和节点亲和性更是可以细粒度的控制应用部署在何处。 强大的调度能力使我们的维护成本降到最低。
  • 简单易用的横向扩展能力:一个命令既可扩容,创建应用的时候调度系统动态分配资源。
  • 强大的社区:google 支持,强大的社区阵容,不用担心没有解决方案

那么 K8S 在实际的场景中能为我们带来什么呢? 我举几个场景吧。

横向扩展提升性能与容量

刚才我们说过面对大规模的持续集成与测试环境时。 面对的每日数以千计甚至数以万计的构建次数。上面还要运行着很多的测试环境。 所以一台机器搞这事铁定是没戏的。如果是以前,我们基本都是在 jenkins 上加入大量的 slave 节点并用 shell 脚本来维护。 但是当节点越来越多的时候,维护这些节点和环境的成本就越来越高了。 所以如果我们能让 k8s 来搞定这些事情,扩容与调度都交给 k8s 来做。 jenkins 只负责 pipline,这就解决了我们自己开发和维护这些节点程序的成本。k8s 的扩容是很简单的。并且它给你一个统一的接口,让你对所有节点和容器的操作只有一个入口。 不会像以前 shell 脚本那样满天飞的节点配置和逻辑判断。 而且 k8s 能够对自我管理这些节点,自动决定把容器调度到哪个合适的节点上,不必我们操心。

精准的按需调度

在一个复杂的场景中,我们不仅需要集群的调度系统能按照当前节点的资源使用情况进行调度,也就是尽量把任务分配到较为空闲的节点上进行负载均衡。 我们还需要更精准的按需调度。 K8S 中有一种策略叫 node selector, 我们通过给集群打上不同的 label 给节点分类,在提交任务的时候可以选择不同类别的节点进行运行。 比如我的数据库是需要存放数据的,而这些数据只存在那一个特定的节点上, 这样我们能通过这样的机制把数据库容器调度到固定的节点上。 当然我们还可以有更强大的调度。比如 GPU 资源再哪里都是稀缺的,我们并不希望大量的普通任务调度到拥有 GPU 的节点上,免得它们把资源占满后会导致真正有 GPU 需求的任务无法调度上来。 k8s 有一种策略叫污点,任务除非在特别指定的情况下,否则是无法调度到这个加了这个污点的 GPU 节点上的。 但这样也有问题,因为这个策略太排他了,实际上如果我的 GPU 任务没有那么多,站不满资源。 那这些剩下的资源还不能被其他任务调度,这个资源利用率是无法忍受的。 所以 k8s 也有第三种调度,叫亲和性和反亲和性。 这个有点复杂,但是它能达到一种效果。 就是它可以优先把普通任务调度到其他节点上,其他的节点不够用的时候,才把这些任务调度到 GPU 节点上。 这样能最大程度的保证其他任务不会影响 GPU 任务还能最大化增加资源率用率。

资源治理

上一点说按需调度的时候,也讲过资源利用率的问题。 我们面临大规模的测试环境的时候, 资源治理是一个非常重要的问题。 公司不是土豪, 我们的资源永远是有限的, 在有限的资源中支撑更多的环境是我们的目标。 我们总在计算着一个节点上能抗多少任务,什么类型的任务。服务起少了,资源利用率低,服务起多了,可能直接把节点撑爆了。 这是一个挺两难的事。所以 k8s 中有 quota 的概念,是一个非常重要的特性。首先启动 k8s 的时候可以设置为系统预留多少资源,这些资源是 k8s 不会使用的,专门留给 linux 系统,以免过多的使用撑爆集群。而且 k8s 把每一个资源都分为两种申请方式。 request 和 limit, request 代表着预留资源,也就是说如果我们为一个设置为 request memory 为 2G。 那么 k8s 就会为它预留 2 个 G 的资源,即便这个任务只用了 1 个 G,但其他任务也无法使用另外一个 G 的资源。 这种策略保证了服务绝对拥有启动服务的最小资源,因为只要申请了,系统就会为你预留这些资源使用。 但是这样的策略有个缺点,就是我们一般无法准确预估出一个服务会用到多少资源,也许他只用了申请资源的一半。 所以我们还有一个中申请资源叫 limit, 他跟 requeset 配合着使用,request 是系统预留的资源,是给任务独占的资源,即便任务根本是用不了这么多的资源,但他也会预留出这些资源给他使用,给一个任务设置过多的这种预留资源肯定是不利于资源利用率的, 但是预留资源少了,也可能造成其他任务抢占资源导致本任务无法运行。 所以 request 一般都是设置成需要运行任务的最小资源。 但是最小资源不代表着他永远都使用这么小的资源,在服务的高峰期的时候他会使用更多的资源。 所以我们有 limit 这种资源申请的方式, 如果说 request 设置的是资源的下限,是任务申请的最小资源, 而 limit 就是任务申请资源的上限,代表着不论如何,任务使用的资源都不可以超过此上限,超过了就会被 k8s kill 掉。确保一个任务不会超出它的预期占用过多的资源。 这样, request 和 limit 相互配合,就会产生更弹性的资源治理方式。 尤其由于他们这两种申请资源的方式存在,我们的系统才会拥有超卖的能力。 超卖是一个在集群管理中常见的词汇。 意思是一个服务本来申请了固定的资源保持平时的开销 (request 方式),但是在服务高峰期的时候,准许分配给他更多的资源,也就是超卖给他更多的资源来抗住高峰期的压力 (limit 方式)。这样就给了我们更加弹性的资源利用方式。

健康检查

之前说过 k8s 有自动化运维的能力, 其中一个重要的能力就是健康检查和故障恢复。 一般来说,在我们面对数量庞大的部署实例的时候, 最头疼的就是如果环境不稳定,比如节点故障,或者进程本身故障的时候,我们该如何维护这些部署实例。 在部署实例还比较少的时候这些都不是问题,我们人肉维护都是可以接受的。 但是当我们有微服务的时候,有多套测试环境的时候,数以百计的部署实例会让所有维护人员都疯掉。 尤其是有些服务的故障可能是很临时性的,比如仅仅是进程 oom 了,或者部署的当前节点发生了什么故障。 并不是进程本身的问题。可能只需要重启或者换个节点重新部署就能解决的问题。那这时候 k8s 的调度能力就起到了很大的作用。 首先 k8s 能够自动监控每个节点的健康状况, 如果 A 节点发生了故障,k8s 会监控到 A 节点是不健康的状态, 那么原来启动在 A 节点上的服务,都会自动的漂移到其他的可用节点上重新启动,来保证我们环境的可用性。 这是节点上的健康检查 。 同时我们也有用服务的健康检查, 在 k8s 中,没启动一个服务都可以为它配置相应的健康检查策略,包括资源的和进程的本身。当任务服务出现异常退出的时候,k8s 都会自动的检测到并在合适的节点上重启该服务,这其中不会有任何的人工操作。这种故障恢复能力,是在我们面对大规模测试环境中要拥有的重要能力。

k8s 还有很多有助于维护我们测试环境的特性,比如驱逐策略,负载均衡,弹性伸缩,init container 等等。这里就不多做介绍了。

下面介绍一下 k8s 最简单的玩法。

  • 在 k8s 中,我们使用 1 个或多个 master 节点来控制集群,之后启动多个 node 节点接入集群。 集群中所有的节点都共享公共的镜像仓库。这样我们把所有需要部署的服务都制作成镜像,就可以为团队提供稳定的测试环境和测试服务的基础 PAAS 平台。 重要的是我们从此拥有了相应的自动化运维和横向扩展的能力。 通过统一的入口可以维护多套测试环境,资源不够了就加节点。 说白了,我们就是在拿钱砸效率。我们在推行微服务之前,在高峰时期曾支撑过 70 套左右的测试环境。 其中包括了各种版本以及对接各个团队的需求。 当然了为了能够维护这种量级的测试环境。 我们需要一些机制上的支撑。

  • 跨主机通信:weave 或 flannel, 玩过 docker 的人都知道网络是第一个要克服的难题。 每个 docker 进程都会自己维护一个私有网络,那么在集群中不同节点上的 docker 容器如何互相通信是一个问题。 所幸目前已经有一些插件支持 k8s 组件一个 overlay 网络。 比如我们曾经使用的 weave 和现在正在使用的 flannel。 它会在集群的每一个节点上都安装一个路由容器,帮助我们转发网络请求。 通过这样构建一个 overlay 网络的形式达到跨节点通信的目的。 而且这些组建都已经有成熟的容器化部署方案,我们直接拿来用就可以

  • 服务发现:kube-dns,docker 容器的另一个特点是容器的 ip 也是随机分配。我们在启动前无法获取 ip,并且在容器重启后 ip 也会发生变化。 所以个成熟的服务发现的机制就比较重要了。 k8s 官方提供的 kubedns 是满足我们的需求的。 在 k8s 中有 service 的概念,我们只要创建一个 service,k8s 集群就会在 kubedns 上创建一个域名指定到这个 service 上。 而每个 service,最后都会转发到我们的容器里面。

  • 7 层路由:ingress, 我们可以通过 dns 和 flannel 这种网络组建解决服务发现和跨主机通信的问题。 但是从集群外部访问集群内部还没有解决。 因为即便是 k8s 的 overlay 网络也只是一个私有的虚拟网络。 如果我们想要从外部访问集群的服务,还需要做一些处理。 最简单的方式是 nodeport,这是一种端口映射规则, 利用 iptables 建立转发规则,把集群节点的端口和容器端口绑定, 这样用户使用 ip+ 端口的方式就可以访问集群服务了。 但是这种方式有一个缺点是需要维护大量的端口映射列表。用户使用起来也很麻烦,起码要记住每一个服务端口号是什么。 所以在这个前提下我们引入了 7 层路由的概念。 其实这个 7 层路由就是一个 nignx, 只不过不同的是它是使用 k8s 中的 hostnetwork 模式启动的,它的特点是直接使用宿主机的网络,而不是使用集群的 overlay 网络,所以这个 nignx 容器是可以和集群外部网络通信的。 同时由于我们安装的 weave 或者 flannel 会在每一个集群节点上安装一个路由容器,它会帮助这个 nginx 容器做转发,所以它也能够访问集群网络。 所以这个使用 hostnetwork 的容器就变成了一个可以同时和集群网络以及外部网络通信的容器。 它也就变成了一个 7 层的路由。 这时候我们在公司内部的 DNS 上配置一个泛域名解析, 凡是以固定域名结尾的请求都解析到这个容器的 ip 上。通过 nignx 识别不同的 service 转发到不同的容器中。就实现了这个 7 层路由的功能。 比如,我们在 nignx 中创建的规则是解析一个域名的 service 部分,然后讲请求转发到对应的 k8s 的 service 上。 一个名字叫 test01.n1.com 的域名和 test02.n1.com 的 service 部分是 test01 和 test02。 nignx 会解析出来然后转发到不同的 k8s service 上。 这块我就不具体详细说明怎么实现的了,大家在网上搜一下 ingress 就可以了。 这是官方的 7 曾路由的解决方案,除了这个 nginx 外还要创建单独的 ingress 规则。 而我们使用的是自研的,省略了这些步骤。

监控:官方的解决方案是 Heapster+grafana+InfluxDB。 可以在 github 上找到现成的镜像使用。我们一开始也是使用这种方式。后来我们慢慢演进到了使用 filebeat 来收集容器日志,灌入 es 中做更精细的日志监控的机制。最近我们已经迁移到另外的一套架构了,不过监控这块不是我负责的,我就不说了。

上面这些都是偏运维的东西,我就不再细讲下去了,

总之我们通过 docker+k8s 就有用了很强大的测试服务能力。 一般我们使用这种机制做一下 3 种事情。

  • 搭建测试环境 (其中包括了 CI,CD 的构成搭建)
  • 搭建测试服务,比如 jira,jenkins,testlink 等
  • 搭建测试执行环境,比如 UI 自动化,接口自动化,线上线下一致性对比测试的执行环境。

这些是我们对于测试的基础 PAAS 平台的架构设计, 对于像机器学习这种复杂度如此之高的系统来说, 我们对这方面有着很高的要求。尤其是在后期我们的产品引入微服务的架构以后,它的复杂度到达了一种空前恐怖的程度。 所以这就需要我们的测试人员能够支撑住这样的基础设施。

CICD

一个高度工程化的团队离不开 CICD,但是面对机器学习平台和微服务架构,我们的 CICD 又有了不一样的难度。 之前说过我们在微服务架构下每日大量的构建次数对 CICD 的性能和自动化流程的要求是很高的。这里我们使用的是 k8s+bamboo+jenkins 的架构。 当然了,所有的构建都是基于 k8s 来做的,使用 k8s 的分布式调度来做横向扩展,解决环境对性能的要求。 利用 bamboo 和 jenkins 的 pipeline 衔接整个 CICD 自动化流程。整个的流程如图:

  • 研发人员任何的提交代码行为都会触发 bamboo 上的 plan,plan 会拉取代码运行单元测试和集成测试,运行成功后会打出一个包作为产物上传到仓库中。如果运行失败,将中断流程,该模块自动报警。
  • 上传成功后触发 bamboo 的 deployment 任务去制作镜像并 push 到镜像仓库中。 这里有一点,如果这里有 CD 的需求,如果这个分支是联调分支,或者是稳定环境。就会触发 CD 任务,利用最新的镜像升级环境。
  • 同时 jenkins 上的 pipeline 每日或触发或定时, 在 k8s 集群上拉取最新的镜像,部署环境,执行 UI 自动化测试,API 自动化测试。并汇总测试报告。

通过这样的 cicd 流程加上 k8s 强大的调度能力,我们支撑着每日千量级别的构建次数的同时,保证了最快的响应速度。 托了 k8s 的自动化运维能力,我们也能够用最少的人去维护这样一个庞大的系统。

机器学习平台下的自动化测试

我们说机器学习平台已经是一个产品了。 所以一个产品该有的东西都会有,我们测试人员关心的 UI 和 API 都会有。 该有的模块也都会有, 比如用户,权限,quota,项目,计划,监控,数据管理等等等。 所以除了机器学习特有的一些特性外,他跟我们普通的测试策略也比较像。 构建测试体系的时候,也符合金字塔原理。 但在这里我们的 CICD 流程中就有了
另一个挑战,那就是测试运行的速度。做机器学习的研发也好,测试也好。 都要面对一个无法避免的问题。 那就是任务运行很慢。 在大数据的情况下,一个模型要用几个小时甚至几天的情况也是不奇怪的。即便我们用一个很小的数据走通业务流程,一般也需要数分钟甚至数十分钟。 所以如果我们像以前一样,使用一个浏览器运行的话,在海量的 case 面前,我们的自动化测试会跑到天荒地老的。 所以在我们早期的时候就会使用多浏览器的方式来为我们的自动化测试加速。 我们使用的技术栈是 java+testng+selenide。 testng 的并发测试模式大家可以了解一下,调整并发的线程数我们就可以在一台机器上启动多个浏览器进行测试。

通过类似上面这样的配置,我们把测试分成了两个组并且并发的去测试他们。 这样在初期的时候还是可以接受的。 但是随着 case 慢慢的增长, 算法越来越多。 我们又出现了一个问题, 那就是单台机器已经无法支撑更多的浏览器了。我们说架构扩容有纵向扩展和横向扩展两种,纵向扩展是通过提高节点的硬件配置来提高性能,但是即便是再优秀的机器它的纵向扩展也是有极限的。 而横向扩展是通过增加节点的方式分担压力。那么目前我们面对的就是在纵向扩展遇到极限的时候,引入横向扩展的能力。 而 testng 本身是不支持跨越多台机器进行分布式执行的。 所以后来我们引入了 selenium gird。 这是一种基于 selenium 的分布式 UI 自动化测试解决方案。 它通过启动一个 grid hub 作为 master 节点,负责接收测试请求以及分发任务。 再通过启动多个 node 节点向 hub 进行注册。 这样 grid hub 会接收到我们的测试请求,并适当的把测试任务均匀的发送到各个 node 上去。 在测试结束后汇总结果返回给 testng。 它的架构是下面这个样子的。

 

通过这样的架构,我们的自动化测试就拥有了横向扩展的能力。 支持更多的浏览器帮助我们进行并发测试。当然大家可以看到在这个图里我们各个节点上都带有 docker 的标记, 为了方便管理和节省资源。 我们也使用容器管理的方式来建设自动化设施。 我们讲 grid hub 制作成镜像,可以运行在 k8s 中当做一个服务。 然后将不同的浏览器制作成不同的镜像。 比如把 chrome 和 Firefox 做成不同的 node 镜像,也通过 k8s 启动服务,注册到 grid hub 中。 当然大家可以发现我们在上面的这个图里在 IE 的镜像那里画一个叉,因为目前 docker 还是无法制作 ie 的镜像的,这涉及到 docker 的原理,docker 使用的是宿主机的内核也就是 linux 系统的内核。 还是无法驱动 windows 的 GUI 的。 所以这部分没有办法,只能够通过在外面启动虚拟机的方式接入 ie 浏览器了。 不过其他两种浏览器还是可以很简单的使用的。 并且通过 k8s 的自动分片的功能,我们可以很方便的启动多个 node 来支持自动化测试。 k8s 强大的调度能力也会在资源上做权衡,做到资源利用最大化,而不会把这些 node 都启动到一个节点上。 同时健康检查机器可以监控到每个 node 和 hub 的状态,如果出现异常会自动的找到可用的节点重新部署。 资源管理能力也可以限制和申请适当的资源,很方便实现的超卖功能。 这样通过 k8s 的自动化运维的能力,我们可以很好的管理我们的浏览器集群。 当然也许会有同学问都是使用 docker 启动的浏览器,那么我们怎么样能够实时的看到浏览器在发生什么呢?以前使用 windows 的时候我们是可以通过界面看到发生的所有事情,方便调试。 其实我们在这里也是可以做到的。 我们在一个 node 镜像中都安装 vnc 服务,并向外暴露端口。 我们在自己的本机上使用 vnc viewer 就可以看到浏览器上发生的一切。

这时候我们的整体工作流程就是下面这个样子的了。

这里我们有两种做法, 一种是 jenkins 直接调用 k8s 的 job,job 执行自动化测试,执行完毕后 jenkins 拉取 report。 另一种做法是直接利用的 jenkins 的 slave 机制,把 slave 直接用 k8s 中的容器的形式启动起来。 这样 j8s 中的一个容器就是 jenkins 的 slave 了。 如果为了简单,我们可以选择后者,利用 k8s 的自动化运维能力,提供稳定的服务。 在 jenkins 上的 job 上绑定测试的 repo,jenkings 触发测试的时候,jenkins 的 salve 会到 git 上拉取代码,并执行自动化测试, 由于我们的 slave 就是启动在 k8s 里的容器,所以他们的访问是无障碍的,甚至完全不需要端口映射和 7 层路由。 slave 的测试请求会发送到同样是启动在 k8s 中的 grid hub 上,gird hub 会把任务发送到同样在 k8s 中作为容器启动的 node 上面去执行。 之后将测试结果一层层的返回,汇总到 jenkins 的 job 中。 这里使用 k8s 的优势就是完全的自动化运维管理,出现任何异常 k8s 都会帮我们处理,这比搭建多个虚拟机来管理要方便便捷很多。 通过这样的架构,在我们的公司的日常测试中使用 40 个浏览器并发测试的方式,可以在 30 分钟内结束战斗。 极大的提升了测试效率。这里在安利一波 selenide,这是一个 github 上面的开源项目, 基于 selenium 做了一层封装。 可以很好的支持我们的这种架构。我们只需要两行代码,就可以对接这种分布式架构了。 如下:

 上面的第一个配置指定使用的浏览器类型,第二个配置指定 grid hub 的地址。 这样就可以让我们的代码测试代码迁移到这个分布式架构上了。 其他的任何代码都不需要改变。 之后的工作只需要在 testng 的配置文件中指定并发数量就可以了。

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方进群即可自行领取。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐