基于Docker+Selenium Grid的测试技术应用示例代码

Selenium Grid介绍

尽管在未来将会推出的Selenium 4.0版本中对Selenium Grid的一些新特性进行了说明,但是目前来看官方并没有太多详细文档供大家参考,所以本书中仍结合目前被广泛使用的Selenium Grid 版本进行讲解。

正如其官网对Selenium Grid的描述,它是一个智能代理服务器,允许Selenium测试将命令路由到远程Web浏览器实例。其目的是提供一种在多台计算机上并行运行测试的简便方法。使用Selenium Grid,一台服务器充当将JSON格式的测试命令路由到一个或多个已注册Grid节点的中枢,以获得对远程浏览器实例的访问。Hub有一个已注册服务器的列表,它可以访问并允许控制这些实例。Selenium Grid允许我们在多台计算机上并行运行测试,并集中管理不同的浏览器版本和浏览器配置。

图1 Selenium Grid的组件构成图

如图1所示,可以看到Selenium Grid主要由2部分构成,即:Hub和Nodes。您可以使用Python、Java、C#等语言编写测试Selenium脚本,每个Selenium Grid仅有一个Hub,客户端脚本可以指定连接到该Hub(主控节点或者叫集线器),Hub接收客户端脚本的运行测试请求,同时将这些测试请求分发到已注册的一个或多个节点去执行并收集运行结果。Selenium Grid中可以一个或多个Node(节点)。作为节点的机器不必与Hub或其他Node具有相同的操作系统或相同的浏览器。即:某个Node节点可能是Windows操作系统,而在该系统上安装的是Internet Explorer浏览器,另外的Node节点可能用的是Linux、Mac操作系统,而它们安装的浏览器可能是Firefox、Safari、Chrome等。这些Node节点的设置结合测试来讲,就是要看您想做那些操作系统、浏览器版本的兼容性测试了,在实际工作中请结合测试执行计划和策略进行选择。

基于Docker的Selenium Grid的相关配置

在Docker Hub中提供了Selenium Grid的相关镜像文件可供使用,如图2所示。

图2 Selenium Grid的相关镜像资源

这里,我们应用“docker pull”命令分别将这3个镜像拉取下来,对应的拉取命令如下:

docker pull selenium/hub
docker pull selenium/node-chrome
docker pull selenium/node-firefox

镜像文件拉取到本地后,您可以使用“docker images”命令查看一下相关镜像的信息,如图3所示。

图3 Selenium Grid的相关镜像信息

这里,先来测试一下Hub与Node节点之间的连通性。

启动Hub,如图4所示。

图4 创建并启动hub容器

创建并启动 chromenode容器节点,如图5所示。

图5 创建并启动chromenode容器节点

创建并启动 firefoxnode容器节点,如图6所示。

图6 创建并启动firefoxnode容器节点

接下来,在本机浏览器地址栏输入“http://localhost:4444/grid/console”,即:打开Selenium Grid的控制台,将出现图7所示页面。

图7 Grid Console控制台信息

从图7可知,当前使用的Selenium Grid 版本为3.141.59版本,对应连接到Hub的两个Node节点分别是IP为172.17.0.4的Linux操作系统使用的是Firefox 75.0版本的浏览器和IP为172.17.0.3的Linux操作系统使用的是Chrome 81.0.4044.92版本的浏览器。在默认情况下Hub节点使用的是4444端口,而Node节点在本例中使用的是5555端口,如果在同一个容器中出现端口冲突等情况,则您需要根据实际情况进行调整设置其他端口以避免端口冲突情况发生。

基于Docker+Selenium Grid的案例演示

下面,笔者将结合Bing搜索案例在Chrome和Firefox浏览器上实现兼容性测试。在经过前面Selenium、Docker和Selenium Grid相关知识的学习后,您想到了什么?是不是可以通过使用Docker+Selenium Grid就能够完成基于不同浏览器的兼容性测试呢?是的,这确实是个好主意。

但是,如果让Selenium测试脚本在不同浏览器中运行,又需要做些什么呢?

在脚本设计上,您需要做一些改变,通常情况下,要在脚本的运行时指定主机和端口,脚本类似于以下方式:

import time
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

driver = webdriver.Remote(
    command_executor='http://192.168.1.102:4444/wd/hub',
    desired_capabilities=DesiredCapabilities.CHROME)

base_url = 'https://cn.bing.com'
driver.get(base_url)
driver.save_screenshot('chrome.png')
driver.close()

通常在执行时,只需指定Hub的地址(即:http://192.168.1.102:4444/wd/hub)。这里宿主机的IP如图8所示, Hub会将脚本自动分配给Node节点去执行。

图8 宿主机的IP地址信息

- command_executor参数:该参数为选填参数,可指定远程服务器URL字符串或自定义远程连接,默认为“http://127.0.0.1:4444/wd/hub”。

- desired_capabilities参数:该参数为必填参数,可根据情况配置启动浏览器会话时请求功能的字典。这里我们应用的是“DesiredCapabilities.CHROME”,您可以查看其对应源代码如下所示。

class DesiredCapabilities(object):
    """
    Set of default supported desired capabilities.
    Use this as a starting point for creating a desired capabilities object for
    requesting remote webdrivers for connecting to selenium server or selenium grid.
    Usage Example::
        from selenium import webdriver
        selenium_grid_url = "http://198.0.0.1:4444/wd/hub"
        # Create a desired capabilities object as a starting point.
        capabilities = DesiredCapabilities.FIREFOX.copy()
        capabilities['platform'] = "WINDOWS"
        capabilities['version'] = "10"
        # Instantiate an instance of Remote WebDriver with the desired capabilities.
        driver = webdriver.Remote(desired_capabilities=capabilities,
                                  command_executor=selenium_grid_url)
    Note: Always use '.copy()' on the DesiredCapabilities object to avoid the side
    effects of altering the Global class instance.
    """

    FIREFOX = {
        "browserName": "firefox",
        "acceptInsecureCerts": True,
    }

    INTERNETEXPLORER = {
        "browserName": "internet explorer",
        "version": "",
        "platform": "WINDOWS",
    }

    EDGE = {
        "browserName": "MicrosoftEdge",
        "version": "",
        "platform": "ANY"
    }

    CHROME = {
        "browserName": "chrome",
        "version": "",
        "platform": "ANY",
    }

    OPERA = {
        "browserName": "opera",
        "version": "",
        "platform": "ANY",
    }

    SAFARI = {
        "browserName": "safari",
        "version": "",
        "platform": "MAC",
    }

    HTMLUNIT = {
        "browserName": "htmlunit",
        "version": "",
        "platform": "ANY",
    }

    HTMLUNITWITHJS = {
        "browserName": "htmlunit",
        "version": "firefox",
        "platform": "ANY",
        "javascriptEnabled": True,
    }

    IPHONE = {
        "browserName": "iPhone",
        "version": "",
        "platform": "MAC",
    }

    IPAD = {
        "browserName": "iPad",
        "version": "",
        "platform": "MAC",
    }

    ANDROID = {
        "browserName": "android",
        "version": "",
        "platform": "ANDROID",
    }

    PHANTOMJS = {
        "browserName": "phantomjs",
        "version": "",
        "platform": "ANY",
        "javascriptEnabled": True,
    }

    WEBKITGTK = {
        "browserName": "MiniBrowser",
        "version": "",
        "platform": "ANY",
    }

    WPEWEBKIT = {
        "browserName": "MiniBrowser",
        "version": "",
        "platform": "ANY",
    }

从DesiredCapabilities类的源码可知“DesiredCapabilities.CHROME”是该类定义的一个字典对象。

这里笔者采用多线程的方式,实现分别在Chrome和Firefox浏览器执行Bing搜索业务,对应脚本如下。

Grid_Test.py文件内容:

from threading import Thread
from selenium import webdriver
from time import sleep,ctime
from selenium.webdriver.common.by import By

def Test_Bing(Host, Browser):
    caps = {'browserName': Browser}
    driver = webdriver.Remote(command_executor=Host, desired_capabilities=caps)
    driver.get('http://www.bing.com')
    driver.find_element(By.ID,'sb_form_q').send_keys('异步社区')
    driver.find_element(By.ID,'sb_form_go').click()
    PicName=Browser+'_result'+'.png'
    driver.save_screenshot(PicName)
    assert ('没有与此相关的结果' not in driver.page_source)
    sleep(2)
    driver.close()

if __name__ == '__main__':
    pcs = {'http://192.168.1.102:4444/wd/hub': 'chrome',
             'http://localhost:4444/wd/hub': 'firefox'
             }
    threads = []
    tds=range(len(pcs))

    # 创建线程
    for host, browser in pcs.items():
        t = Thread(target=Test_Bing, args=(host, browser))
        threads.append(t)

    # 启动线程
    for i in tds:
        threads[i].start()
    for i in tds:
        threads[i].join()

从上面的脚本,大家可以看到创建了一个名称为Test_Bing()的函数,其包含两个参数,分别是主机和浏览器。函数的执行意图就是根据远程服务器URL字符串和传入的浏览器名称字符串,在对应的浏览器中执行搜索业务,且搜索词为“异步社区”,对执行结果进行截图,截图的名称为对应浏览器名称+“_result.jpg”文件,并对搜索后的结果进行断言。需要说明的是,这里对结果进行截图的目的不仅仅是想看一下结果,还有一个很重要的原因是在使用Selenium Grid时,执行测试过程中不会出现浏览器,所以您看不到执行过程,为了证明结果的正确性我们也需要截一个图证明其确实是工作了并且执行是正确的。如果您还想看到不同的容器在执行过程中的界面,也可以使用VNC Viewer连接到对应容器(但需下载对应的selenium/node-firefox-debug和selenium/node-chrome-debug镜像文件,debug结尾的镜像都带有VNC服务端,本机安装VNC客户端,即可远程连接。5900端口为VNC Viewer的监听端口,故做了一个端口映射),如图9和图10所示。

图9 创建并启动Debug版本的节点容器

图10 VNC Viewer观察节点容器的脚本执行情况

事实上这对于测试工作并没有太多意义,故不做太多文字赘述。

在主函数中,定义了一个包含2个元素的字典,大家可以看到笔者使用了2种同一个地址不同的表示方式(宿主机的IP地址为192.168.1.102),而“localhost”也表示本机,即宿主机。那么为什么不都用“192.168.1.102”或者“localhost”呢?这是因为字典的键(Key)是不允许重复的。接下来创建了一个线程列表,以pcs字典的键、值作为Test_Bing()函数的参数,并添加到线程列表。而后启动线程列表中的各线程。

在运行脚本前,需保证创建并启动Hub和Node节点容器(注:这里笔者应用的为非Debug版本Node镜像),如图11所示。

图11 创建并启动Hub和Node节点容器

脚本执行完成后,将会生成“chrome_result.jpg”和“firefox_result.jpg”这2个图片文件,如图12所示。

图12 脚本执行完成后生成的图片文件信息

如图13和图14所示,在本次兼容性测试中大家可以看到这2个浏览器都执行了相同的Bing搜索业务,它们的页面展示、布局、内容基本是相同的,但是却存在2个小的问题,就是在Chrome浏览器中搜索到的结果为“855,000 Results”,而Firefox浏览器中搜索到的结果为“859,000 Results”,它们是不一致的。另一个小问题是,在Firefox浏览器会显示“Sign in”和一个登陆图标,而在Chrome浏览器中却没有。理论上来讲这是2个严重级别较低的小Bug,但笔者建议针对这两个小的差异,需要和产品、研发的同学再确认一下,产品、测试、研发应统一、明确需求,明确后再修改需求或代码,使两者保持一致。

图13 chrome_result.jpg图片文件信息

图14 firefox_result.jpg图片文件信息

到此这篇关于基于Docker+Selenium Grid的测试技术应用示例代码的文章就介绍到这了,更多相关Docker Selenium Grid测试技术内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Docker+selenium实现自动化健康报备的方法

    本文以某高校的健康报备系统为例,完成该web端的自动化操作,用到的技术栈如下所述: Docker \ Selenium \ Python \ yagmail \ ssh等 基本思路: 1.本地编写代码并进行测试 2.新建docker容器并配置环境 3.代码上传到服务器并复制到docker容器内 4.解压.调试代码,确认代码没有问题后删除代码 6.退出容器,并将容器制作成镜像 7.用镜像实例化容器并挂载代码 一.本地编写代码并调试 先看一下我们需要进行操作的目标web: 登录页面: 表单页面: 操

  • 用docker搭建selenium grid分布式环境实践之路

    最近需要测试zoom视频会议,同时模拟100个人加入会议.经过了解,zoom提供了直接通过url链接加入会议的方式(只能通过chrome浏览器或者FireFox浏览器,因为用的协议是webrtc). 顺着这个思路考虑可以通过Selenium自动化,同时启动多个浏览器进程,每个进程代表一个视频会议用户,达到模拟多方会议的效果.不过有以下两个难点: 需要多个chrome浏览器进程同时存活,在电脑上启动一个chrome浏览器进程差不多要消耗220M左右. 视频会议的音频和视频源的问题. 针对视频会议的

  • 基于docker搭建selenium分布式环境

    1.下载镜像 docker pull selenium/hub docker pull selenium/node-firefox docker pull selenium/node-chrome 注意:selenium/node-firefox和selenium/node-chrome都是无界面的. 要想能看到实时运行界面,需要使用以下两个镜像之一. docker pull selenium/standalone-chrome-debug docker pull selenium/standa

  • docker利用selenium+testng实现web自动化的方法

    前言 经历了漫长的各种资料,终于把selenium+testng参数化的问题搞定了!可能网上能找到一些,但是这些都是自己的经历.本文主要介绍了关于docker利用selenium+testng实现web自动化的相关内容,下面话不多说了,来一起看看详细的介绍吧 Windows下selenium+testng的web自动化环境搭建 做过自动化的人,肯定对selenium web环境的搭建非常熟悉了,特别是selenium在java中的使用. 先搭建好安装好JDK,配置好java开发环境(这个如果还是

  • 基于Docker+Selenium Grid的测试技术应用示例代码

    Selenium Grid介绍 尽管在未来将会推出的Selenium 4.0版本中对Selenium Grid的一些新特性进行了说明,但是目前来看官方并没有太多详细文档供大家参考,所以本书中仍结合目前被广泛使用的Selenium Grid 版本进行讲解. 正如其官网对Selenium Grid的描述,它是一个智能代理服务器,允许Selenium测试将命令路由到远程Web浏览器实例.其目的是提供一种在多台计算机上并行运行测试的简便方法.使用Selenium Grid,一台服务器充当将JSON格式的

  • 基于Docker实现Redis主从+哨兵搭建的示例实践

    目录 1.拉取镜像 2. 编写主 从配置文件 2.1 创建/home/redis/redis_conf目录: 2.2 编写主配置文件 2.3 编写从配置文件 2.4  编写从配置文件 3 编写sentinel配置文件 3.1创建哨兵配置文件 3.2编写哨兵配置文件 4  启动主节点容器 4.1启动主节点容器 4.2 启动从节点容器 5 存在的问题: 6.分别启动每个  docker容器里面的哨兵 6.1进入主节点容器 6.2查看文件 6.3启动主哨兵服务 6.4 启动两个从哨兵服务 6.5进入主

  • selenium+python实现基本自动化测试的示例代码

    安装selenium 打开命令控制符输入:pip install -U selenium 火狐浏览器安装firebug:www.firebug.com,调试所有网站语言,调试功能 Selenium IDE 是嵌入到Firefox 浏览器中的一个插件,实现简单的浏览器操 作的录制与回放功能,IDE 录制的脚本可以可以转换成多种语言,从而帮助我们快速的开发脚本,下载地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/ 如何使用

  • 基于Java实现QQ登录注册功能的示例代码

    目录 前言 实现代码 登录页面 注册页面 效果展示 前言 本文主要应用的技术有:GUI.JDBC.多线程 实现的功能具体如下: 1.登录功能 2.注册功能 3.是否隐藏密码的选择以及实现功能 4.选择性别功能 5.密码与确认密码功能 6.登录页面实时展示当前的时间 7.当登录时用户名与密码在数据库中没有相匹配的数据,则会跳转到注册页面上去. 8.同样,注册完毕后,数据会运用JDBC将数据写入数据库中,然后跳转回登录页面. 实现代码 登录页面 import javax.swing.*; impor

  • 基于C语言实现三子棋游戏的示例代码

    1.创建文件  test.c (游戏的测试逻辑)game.c(游戏的实现逻辑)gane.h(游戏实现函数的声明) game.c 和game.h属于游戏实现 test.c属于游戏测试 test.c 源文件(源文件添加)——game.c 源文件(源文件添加)——game.h(头文件添加) 三个文件 2.首先在test.c文件写一个主函数,主函数里面有一个测试函数,测试函数里面写菜单.进入游戏.退出游戏 代码展示: void menu() { printf("*********************

  • 基于Python制作天眼查小程序的示例代码

    目录 界面搭建 整体布局 界面美化 天眼查爬虫 获取信息 代码编写 结果展示 今天我们一起来制作一个天眼查GUI程序,开宗明义,我们先来看下最终的效果 这次的GUI程序,我们使用的框架是PyQt5,该框架拥有比tkinter更为丰富的内置组件,在界面美化方面,貌似也更胜一筹! 从上图也可以看出,我们的目标还是蛮远大的,最终我们希望可以完成一个工具集合,把我们日常当中常用的功能都集成的该GUI程序中,比如天眼查公司信息,知乎用户知识图谱,B视频弹幕抓取等等. 好了,今天我们先完成天眼查的功能吧~

  • 基于Vue2x的图片预览插件的示例代码

    本文介绍了基于Vue2x的图片预览插件的示例代码,分享给大家,具体如下: 先来看下Demo LiveDemo 关于开发Vue插件的几种方式 (具体请移步官网)Vue官网 MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或属性 Vue.myGlobalMethod = function () { // 逻辑... } // 2. 添加全局资源 Vue.directive('my-directive', { bind (el, bin

  • C# 利用Selenium实现浏览器自动化操作的示例代码

    概述 Selenium是一款免费的分布式的自动化测试工具,支持多种开发语言,无论是C. java.ruby.python.或是C# ,你都可以通过selenium完成自动化测试.本文以一个简单的小例子,简述C# 利用Selenium进行浏览器的模拟操作,仅供学习分享使用,如有不足之处,还请指正. 涉及知识点 要实现本例的功能,除了要掌握Html ,JavaScript,CSS等基础知识,还涉及以下知识点: log4net:主要用于日志的记录和存储,本例采用log4net进行日志记录,便于过程跟踪

  • Java Selenium实现多窗口切换的示例代码

    在web应用中,常常会遇见点击某个链接会弹出一个新的窗口,或者是相互关联的web应用 ,这样要去操作新窗口中的元素,就需要主机切换到新窗口进行操作.WebDriver 提供了switchTo().window()方法可以实现在不同的窗口之间切换. 获取当前窗口浏览器句柄:driver.getWindowHandle(); 获取所有窗口的浏览器句柄到当前会话:driver.getWindowHandles(); 用于不同窗口的切换:switchTo().window(); 在页面操作过程中有时候点

  • 基于Java的MathML转图片的方法(示例代码)

    Maven依赖: <dependency> <groupId>de.rototor.jeuclid</groupId> <artifactId>jeuclid-core</artifactId> <version>3.1.14</version> </dependency> 示例: @Test public void testMathMlToImg() throws IOException { //MathML

随机推荐