如何在 Selenium Grid 上对两个单例浏览器进行多线程处理?
How to multithread two singleton browsers on Selenium Grid?
我正在构建一个项目,偶然发现了使用 Selenium Grid 的多线程。我有两个浏览器设置扩展了我需要的 selenium 包装页面 运行(Chrome 驱动程序和 Firefox 驱动程序)。
分别看了很多关于多线程和单例模式的文章,但是不知道如何让它们一起工作。
测试:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="selenium" verbose="1" thread-count="2" parallel="tests">
<test name="ChromeTest">
<parameter name="browserName" value="chrome"/>
<classes>
<class name="Run.CucumberRunner"/>
</classes>
</test>
<test name="FirefoxTest">
<parameter name="browserName" value="firefox"/>
<classes>
<class name="Run.CucumberRunner"/>
</classes>
</test>
</suite>
黄瓜运行纳尔:
@CucumberOptions(
features = "src/test/resources/features",
glue = "Run",
plugin = "io.qameta.allure.cucumber4jvm.AllureCucumber4Jvm"
)
public class CucumberRunner extends AbstractTestNGCucumberTests {
private static final Logger LOG = LogManager.getLogger(CucumberRunner.class);
@Parameters({"browserName"})
@BeforeTest()
public void setUp(String browserName) {
if (browserName.equals("chrome")){
CustomChromeDriver chromeDriver = CustomChromeDriver.getInstance();
} else if (browserName.equals("firefox")){
CustomFirefoxDriver firefoxDriver = CustomFirefoxDriver.getInstance();
}
}
}
其中一个浏览器实例:
class CustomChromeDriver extends BasicDriver {
private String HUB = "http://192.168.2.105:4444/wd/hub";
private WebDriverWait wait;
private static CustomChromeDriver chrome;
public static CustomChromeDriver getInstance() {
if (chrome == null) {
chrome = new CustomChromeDriver();
}
return chrome;
}
private CustomChromeDriver() {
wait = new WebDriverWait(remoteWebDriver, 10);
System.setProperty("webdriver.chrome.driver", "bin/chromedriver.exe");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
try {
remoteWebDriver = new RemoteWebDriver(new URL(HUB), capabilities);
} catch (MalformedURLException e) {
}
}
}
步骤定义:
public class StepDefinitions {
private MainPage mainPage = new MainPage();
private static final Logger LOG = LogManager.getLogger(StepDefinitions.class);
private String testHost = "https://www.google.com/gmail/";
@Step ("Opening test host")
@Given("test host open")
public void openHost() {
mainPage.navigate(this.testHost);
LOG.debug("Test host opened");
}
页面对象的父页面
public abstract class BasicPage {
public BasicDriver basicDriver;
public void navigate(String url) {
basicDriver.get(url);
}
public void shutDown(){
basicDriver.close();
}
}
堆栈跟踪片段:
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at org.openqa.selenium.support.ui.FluentWait.<init>(FluentWait.java:106)
at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:85)
at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:45)
at Run.CustomChromeDriver.<init>(CustomChromeDriver.java:49)
at Run.CustomChromeDriver.getInstance(CustomChromeDriver.java:37)
您在实例化之前使用了 remoteWebDriver
下面的区块
try {
remoteWebDriver = new RemoteWebDriver(new URL(HUB), capabilities);
} catch (MalformedURLException e) {
}
应该在这一行之前
wait = new WebDriverWait(remoteWebDriver, 10);
System.setProperty("webdriver.chrome.driver", "bin/chromedriver.exe");
由于 remoteWebDriver 没有被实例化,你得到 NullPointerException。
- 你脚本的主要问题是你在尝试
通过提供尚未初始化的
remoteWebDriver
实例来实例化 WebDriverWait。
- 考虑删除
static
access modifier from any classes which assume WebDriver 和衍生用法
- 考虑放置 WebDriver 和所有不是 thread-safe into ThreadLocal
的实体
我正在构建一个项目,偶然发现了使用 Selenium Grid 的多线程。我有两个浏览器设置扩展了我需要的 selenium 包装页面 运行(Chrome 驱动程序和 Firefox 驱动程序)。
分别看了很多关于多线程和单例模式的文章,但是不知道如何让它们一起工作。
测试:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="selenium" verbose="1" thread-count="2" parallel="tests">
<test name="ChromeTest">
<parameter name="browserName" value="chrome"/>
<classes>
<class name="Run.CucumberRunner"/>
</classes>
</test>
<test name="FirefoxTest">
<parameter name="browserName" value="firefox"/>
<classes>
<class name="Run.CucumberRunner"/>
</classes>
</test>
</suite>
黄瓜运行纳尔:
@CucumberOptions(
features = "src/test/resources/features",
glue = "Run",
plugin = "io.qameta.allure.cucumber4jvm.AllureCucumber4Jvm"
)
public class CucumberRunner extends AbstractTestNGCucumberTests {
private static final Logger LOG = LogManager.getLogger(CucumberRunner.class);
@Parameters({"browserName"})
@BeforeTest()
public void setUp(String browserName) {
if (browserName.equals("chrome")){
CustomChromeDriver chromeDriver = CustomChromeDriver.getInstance();
} else if (browserName.equals("firefox")){
CustomFirefoxDriver firefoxDriver = CustomFirefoxDriver.getInstance();
}
}
}
其中一个浏览器实例:
class CustomChromeDriver extends BasicDriver {
private String HUB = "http://192.168.2.105:4444/wd/hub";
private WebDriverWait wait;
private static CustomChromeDriver chrome;
public static CustomChromeDriver getInstance() {
if (chrome == null) {
chrome = new CustomChromeDriver();
}
return chrome;
}
private CustomChromeDriver() {
wait = new WebDriverWait(remoteWebDriver, 10);
System.setProperty("webdriver.chrome.driver", "bin/chromedriver.exe");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
try {
remoteWebDriver = new RemoteWebDriver(new URL(HUB), capabilities);
} catch (MalformedURLException e) {
}
}
}
步骤定义:
public class StepDefinitions {
private MainPage mainPage = new MainPage();
private static final Logger LOG = LogManager.getLogger(StepDefinitions.class);
private String testHost = "https://www.google.com/gmail/";
@Step ("Opening test host")
@Given("test host open")
public void openHost() {
mainPage.navigate(this.testHost);
LOG.debug("Test host opened");
}
页面对象的父页面
public abstract class BasicPage {
public BasicDriver basicDriver;
public void navigate(String url) {
basicDriver.get(url);
}
public void shutDown(){
basicDriver.close();
}
}
堆栈跟踪片段:
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at org.openqa.selenium.support.ui.FluentWait.<init>(FluentWait.java:106)
at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:85)
at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:45)
at Run.CustomChromeDriver.<init>(CustomChromeDriver.java:49)
at Run.CustomChromeDriver.getInstance(CustomChromeDriver.java:37)
您在实例化之前使用了 remoteWebDriver
下面的区块
try {
remoteWebDriver = new RemoteWebDriver(new URL(HUB), capabilities);
} catch (MalformedURLException e) {
}
应该在这一行之前
wait = new WebDriverWait(remoteWebDriver, 10);
System.setProperty("webdriver.chrome.driver", "bin/chromedriver.exe");
由于 remoteWebDriver 没有被实例化,你得到 NullPointerException。
- 你脚本的主要问题是你在尝试
通过提供尚未初始化的
remoteWebDriver
实例来实例化 WebDriverWait。 - 考虑删除
static
access modifier from any classes which assume WebDriver 和衍生用法 - 考虑放置 WebDriver 和所有不是 thread-safe into ThreadLocal 的实体