微信公众号:测试工程师成长之路
关注可了解更多的测试技术。问题或建议,请添加微信好友;
如果你觉得公众号对你有帮助,欢迎推荐给他人
上一篇文章讲了如何通过Selenium Grid做分布式自动化测试,不清楚的可以点击手把手教你使用Selenium Grid实现分布式自动化测试进行阅读。
上次我们遇到一个问题,就是我们在执行脚本的时候,发现每次只能在一个Node上面执行浏览器操作,我们在执行脚本的时候,如何在多个Node上同时执行浏览器操作呢?
一、ThreadLocal简介
ThreadLocal是JDK包提供的,它提供线程本地变量,如果创建一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个副本,在实际多线程操作的时候,操作的是自己本地内存中的变量,从而规避了线程安全问题。
1import org.openqa.selenium.WebDriver;
2
3/**
4 * @author 作者:测试工程师成长之路
5 * @version 创建时间:2021/7/31
6 * 类说明:
7 */
8public class BrowserUtils {
9 private static ThreadLocal<WebDriver> threadLocal = new ThreadLocal<>();
10
11 /**
12 * 从线程ThreadLocal获取存放的驱动
13 * @return
14 */
15 public static WebDriver getDriver(){
16 return threadLocal.get();
17 }
18
19 /**
20 * 将驱动设置给线程ThreadLocal
21 * @param driver
22 */
23 public static void setDriver(WebDriver driver){
24 threadLocal.set(driver);
25 }
26}
二、启动Hub和Node
1#启动hub
2java -jar selenium-server-standalone-3.5.3.jar -role hub
3
4#启动Node1和Node2
5#分别在两台机器上执行命令
6java -jar selenium-server-standalone-3.5.3.jar -role node -port 5555 -hub http://hub ip:4444/grid/register -maxSession 5 -browser browserName=chrome,seleniumProtocol=WebDriver,maxInstances=5
三、测试脚本修改
1import org.openqa.selenium.By;
2import org.openqa.selenium.Keys;
3import org.openqa.selenium.Platform;
4import org.openqa.selenium.WebDriver;
5import org.openqa.selenium.remote.DesiredCapabilities;
6import org.openqa.selenium.remote.RemoteWebDriver;
7import org.testng.annotations.Test;
8
9import java.net.MalformedURLException;
10import java.net.URL;
11
12/**
13 * @author 作者:测试工程师成长之路
14 * @version 创建时间:2021/7/19
15 * 类说明:Selenium Grid
16 */
17public class SeleniumGridTest {
18 public static final String browserName = "chrome";
19
20 @Test
21 public void testGrid() throws InterruptedException {
22 try {
23 // System.setProperty("webdriver.chrome.driver","D:\\software\\selenium\\chromedriver.exe");
24
25 DesiredCapabilities capability = new DesiredCapabilities();
26 capability.setBrowserName(browserName);
27 capability.setPlatform(Platform.WINDOWS);
28
29 WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
30 BrowserUtils.setDriver(driver);
31 BrowserUtils.getDriver().get("http://www.baidu.com");
32 BrowserUtils.getDriver().manage().window().maximize();
33 Thread.sleep(3000);
34 //输入 hadoop查询
35 BrowserUtils.getDriver().findElement(By.id("kw")).sendKeys("mrjade" + Keys.ENTER);
36 Thread.sleep(3000);
37 BrowserUtils.getDriver().findElement(By.xpath("//*[@id=\"1\"]/h3/a")).click();
38 Thread.sleep(5000);
39
40 BrowserUtils.getDriver().close();
41 BrowserUtils.getDriver().quit();
42
43 } catch (MalformedURLException e) {
45 e.printStackTrace();
46 }
47 }
48}
四、testng.xml配置
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
3<suite name="Suite" parallel="tests" thread-count="2">
4 <test name="Test1">
5 <classes>
6 <class name="SeleniumGridTest">
7 <methods>
8 <include name="testGrid"></include>
9 </methods>
10 </class>
11 </classes>
12 </test>
13 <test name="Test2">
14 <classes>
15 <class name="SeleniumGridTest">
16 <methods>
17 <include name="testGrid"></include>
18 </methods>
19 </class>
20 </classes>
21 </test>
22</suite>
说明:parallel
该参数的值false,methods,tests,classes,instances。默认false,必须和thread-count配套使用,否则相当于无效参数,thread-count决定了并行测试时开启的线程数量。
1.parallel=“mehods”:TestNG将并行执行所有的测试方法在不同的线程里。
2.parallel=“tests”:TestNG将并行执行在同一个标签下的所有方法在不同线程里。
3.parallel=“classes”:TestNG将并行执行在相同下的方法在不同线程里。
4.parallel=“instances”:TestNG将并行执行相同实例下的所有方法在不同的线程里。
五、遗留问题
上述代码可以实现在不同Node上同时启动chrome浏览器,那么如何分别启动chrome和firefox呢,在尝试过程中发现无法启动firefox,可能是版本方面不兼容导致,但是尝试了好几个版本依然没有解决,以下是尝试过的版本信息
1firefox version:56,60
2geckodriver version:0.18.0,0.19.0,0.20.0
3selenium version:3.5.3
附:selenium与firefox,geckodriver版本映射表
因为考虑到chrome版本与selenium版本兼容性的问题,所以就没有尝试不同selenium版本去启动firefox,有兴趣的小伙伴可以去尝试尝试。
往期推荐: