Selenium Grid是Selenium的三大组件之一,它的作用就是分布式执行测试,在不同机器上测试不同浏览器,他的整体结构是由一个hub节点和至少一个node节点组成,hub用来管理各个node节点的注册和状态信息,并且接受远程客户端代码的请求调用,然后把请求的命令再转发给node节点来执行。
·这个对外的老大对应的是 Selenium Hub;
·具体执行任务的手下,对应的是 Selenium Node;
·老大接到任务后分配给手下执行的过程,就是 Selenium Hub 将测试分配到 Selenium Node 执行的过程;
·老大的手下向他报备自己技能的过程,就是 Selenium Node 向 Selenium Hub 注册的过程。
也就是说,Selenium Hub 用来管理各个 Selenium Node 的注册信息和状态信息,并且接收远程客户端代码的测试调用请求,并把请求命令转发给符合要求的 Selenium Node 执行。
主要解决问题:
1、 解决了多浏览器的兼容性,减少测试套件运行时间。
2、 远程操作时,不需要远程机器上有测试脚本
!!虽然可以分布式执行测试用例,但它并不支持并行,如果需要并行执行的话还是需要用到testNG自带的多线程,然后使用thread local解决线程安全的问题。
普通调用Selenium-Grid的基本结构图如下 (当测试用例比较多时,可以平行的执行这些用例进而缩短测试总耗时):
此外,selenium-grid还支持一种更友好的功能,可以根据用例中启动测试的类型来相应的把用例转发给符合匹配要求的测试代理。例如你的用例中指定了要在Liunux上FF的3.6版本进行测试,那么selenium-grid会自动匹配注册信息为Linux、且安装了FF3.6的代理节点,如果匹配成功则转发测试请求,如果失败则拒绝请求。使用selenium-grid的远程兼容性测试的代码同上。其调用的基本结构图如下:
环境部署说明:
本文使用selenium-server-standalone-2.53.0.jar举例,hub、node节点机器上均需要该jar包启动,同一台电脑可以同时作为hub和node使用
准备工作:
1、 安装jdk运行环境,
2、 准备selenium-server-standalone-2.53.1.jar,,执行后出现如下页面则启动成功:java -jar selenium-server-standalone-<version>.jar -role hub。在这条命令中,“-role hub”的作用是将该机器启动为 Selenium Hub。启动完成后,这台机器默认对外提供服务的端口是 4444。
然后,你就可以在这台机器上通过http://localhost:4444/grid/console观察 Selenium Hub 的状态,也可以在其他机器上通过 http://<Hub_IP>:4444/grid/console 观察 Selenium Hub 的状态。其中,<Hub_IP> 是这台 Selenium Hub 机器的 IP 地址。出现如下页面
3、 准备对应浏览器版本的driver
**其中jar包和driver建议放在同一目录下,并在该目录下使用cmd启动(jar包和chrome驱动在附件中)
节点信息如下:
hub机 => ip:10.161.56.128
node1机 => ip:10.161.56.128
node2机 => ip:10.161.38.136
1、启动hub节点:
启动命令为:java -jar selenium-server-standalone-2.53.1.jar -role hub -maxSession 10 -port 4444 -Hubhost 10.161.56.128
参数
-role hub表示启动运行hub;
-port是设置端口号,hub的默认端口是4444,也可以自己配置;
-maxSession为最大会话请求,这个参数主要要用并发执行测试用例,默认是1,建议设置10及以上。
浏览器打开地址:http://10.161.56.128:4444/grid/console,出现Crid Console的页面表示hub启动成功。
###也可以写成bat文件,格式如下:
@echo off
D:\Users\LUOKANG880\eclipse-workspaceWeb\ZZ_TesterHome\lib
java -jar selenium-server-standalone-2.53.1.jar -role hub -port 4444 -Hubhost 10.161.56.128
2、启动node节点
2.1、启动nide1节点,配置对应浏览器(如chrome),运行命令为:java -jar selenium-server-standalone-2.53.0.jar -role node -port 5555 -hub http://10.161.56.128:4444/grid/register -Dwebdriver.chrome.driver=chromedriver.exe -maxSession 5 -browser browserName=chrome,seleniumProtocol=WebDriver,maxInstances=5,platform=WINDOWS
再次刷新一下http://10.161.56.128:4444/grid/console,会发现node节点已经显示,表示启动成功。
参数解析:
-role node:表示启动的是node节点
-port 5555:指定node节点端口
-hub http://10.161.56.128:4444/grid/register:表示hub机地址
-Dwebdriver.chrome.driver=chromedriver.exe :浏览器插件,如果是其他浏览器就写对应的名字
-maxSession 5:node节点最大会话请求
-browser browserName=firefox,seleniumProtocol=WebDriver,
maxInstances=5,platform=WINDOWS,version=45.0.2 浏览器的参数;browserName表示浏览器名字,如chrome、firefox、ie;maxInstances表示最大实例,可以理解为最多可运行的浏览器数,这个值很关键,不能大于前面maxSession的值,否则可能会出错;platform表示操作系统;version表示浏览器版本。
**也可以写成bat文件,格式如下:
@echo off
D:\Users\LUOKANG880\eclipse-workspaceWeb\ZZ_TesterHome\lib
java -jar selenium-server-standalone-2.53.0.jar -role node -port 5555 -hub http://10.161.56.128:4444/grid/register -Dwebdriver.chrome.driver=chromedriver.exe -maxSession 5 -browser browserName=chrome,seleniumProtocol=WebDriver,maxInstances=5,platform=WINDOWS
2.2、同理:在node2机器上启动node2节点,刷新http://10.161.56.128:4444/grid/console,会发现node节点已经显示,表示启动成功;
编写java脚本:
package testGrid;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class testngsuitbrid {
private WebDriver driver;
DesiredCapabilities browsers;
@Parameters({ "browser", "nodeIp" })
@Test(invocationCount = 5, threadPoolSize = 5)//case运行invocationCount次数,最大并发数threadPoolSize
public void setUp(String browser, String nodeIp) {
if (browser.equals("ie"))
browsers = DesiredCapabilities.internetExplorer();
else if (browser.equals("firefox"))
browsers = DesiredCapabilities.firefox();
else if (browser.equals("chrome"))
browsers = DesiredCapabilities.chrome();
try {
driver = new RemoteWebDriver(new URL(nodeIp + "/wd/hub"), browsers);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driver.get("https://www.baidu.com/");
// 查看用的哪个进程
long id = Thread.currentThread().getId();
System.out.println("Thread id is: " + id);
driver.close();//关闭在实际使用中发现无法关闭所有打开的浏览器,具体原因待验证
}
编写xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="testerHome-个人中心" parallel="tests" thread-count="5">
<test name="Test-1">
<parameter name="browser" value="chrome" />
<parameter name="nodeIp" value="http://10.161.56.128:5555" />
<classes>
<class name="testGrid.testngsuitbrid">
</class>
</classes>
</test>
<test name="Test-2">
<parameter name="browser" value="chrome" />
<parameter name="nodeIp" value="http://10.161.38.136:7777" />
<classes>
<class name="testGrid.testngsuitbrid">
</class>
</classes>
</test>
</suite>
使用testNG运行,分别在hub和node机上的浏览器可以正常启动,每台机器启动5个浏览器并行打开百度页面成功,则远程环境搭建完成。
基于 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 的官方文档。
接下来,你就可以通过以下命令分别启动 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 都将是最好的选择。关于这部分内容具体的细节,我会在后面两篇文章中详细展开。