java - 无法让测试方法与硒网格并行运行
问题描述
所以我有一个 selenium 网格集线器,一个为每个浏览器注册了 5 个实例的节点(Safari 12.1.2、Firefox 69.0、Chrome 76.0)。每当我尝试使用并行方法和 thread-count=2 或更多方法运行测试时,我都会不断收到有关会话创建问题的错误消息。很奇怪,但 Chrome 中的测试通过(有时 Safari 中的测试也会通过)。我相信测试脚本是好的。我相信这个问题与方法共享相同的浏览器会话有关,尽管我实现了线程安全方法,但是,一定有我错过的东西。我认为问题出在 TestBase.class 的某个地方,但不确定。ide 用完了。请指教。
Selenium Grid 3 Selenium-java 库:v 3.141.59 java.version:'11.0.4' Safari 12.1.2、Firefox 69.0、Chrome 76.0
这是我的配置节点:
browserTimeout: 0
debug: false
help: false
port: 4445
role: node
timeout: 1800
cleanUpCycle: 5000
host: 169.254.129.238
maxSession: 5
capabilities: Capabilities {browserName: firefox, browserVersion: 69.0, maxInstances: 5, platform: MAC, platformName: mac, se:CONFIG_UUID: 42a26507-e6b8-4463-a6e3-fd7..., seleniumProtocol: WebDriver}
capabilities: Capabilities {browserName: chrome, browserVersion: 76.0, maxInstances: 5, platform: MAC, platformName: mac, se:CONFIG_UUID: c6a7fd21-84cb-4295-be81-cd6..., seleniumProtocol: WebDriver}
capabilities: Capabilities {browserName: safari, browserVersion: 12.1.2, maxInstances: 5, platform: MAC, platformName: mac, se:CONFIG_UUID: 606e350d-f4b7-405a-a772-6c7..., seleniumProtocol: WebDriver}
downPollingLimit: 2
hub: http://localhost:4444
id: http://169.254.129.238:4445
nodePolling: 5000
nodeStatusCheckTimeout: 5000
proxy: org.openqa.grid.selenium.proxy.DefaultRemoteProxy
register: true
registerCycle: 5000
remoteHost: http://169.254.129.238:4445
unregisterIfStillDownAfter: 60000
My testng.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="3" name="Suite" parallel="tests">
<listeners>
<listener class-name="Base.TestListener"/>
<!--<listener class-name="Base.RetryListener"/>-->
</listeners>
<parameter name="appURL" value="https://www.google.com"/>
<test name="Chrome_tests" parallel="methods" thread-count="2">
<parameter name="browser" value="chrome"/>
<parameter name="browser_version" value="76.0"/>
<parameter name="platform" value="mac"/>
<classes>
<class name="Tests.FirstTest">
<methods>
<include name="GOOGLE1" />
<include name="GOOGLE2" />
<include name="GOOGLE3" />
</methods>
</class>
</classes>
</test>
<test name="Firefox_tests" parallel="methods" thread-count="2">
<parameter name="browser" value="firefox"/>
<parameter name="browser_version" value="69.0"/>
<parameter name="platform" value="mac"/>
<classes>
<class name="Tests.FirstTest">
<methods>
<include name="GOOGLE1"/>
<include name="GOOGLE2"/>
<!--<include name="GOOGLE3" />-->
</methods>
</class>
</classes>
</test> <!-- Second Test -->
<test name="Safari_tests" parallel="methods" thread-count="1">
<parameter name="browser" value="safari"/>
<parameter name="browser_version" value="12.1.2"/>
<parameter name="platform" value="mac"/>
<classes>
<class name="Tests.FirstTest">
<methods>
<include name="GOOGLE1"/>
<include name="GOOGLE2"/>
<!--<include name="GOOGLE3" />-->
</methods>
</class>
</classes>
</test> <!-- Second Test -->
</suite>
我的 TestBase.class
public class TestBase {
//Declare ThreadLocal Driver (ThreadLocalMap) for ThreadSafe Tests
public ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<>();
public CapabilityFactory capabilityFactory = new CapabilityFactory();
@BeforeMethod
@Parameters({"browser", "appURL", "browser_version", "platform"})
public void setup (String browser, String appURL, String browser_version, String platform) throws MalformedURLException {
//Set Browser to ThreadLocalMap
driver.set(new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilityFactory.getCapabilities(browser, browser_version, platform)));
getDriver().manage().window().maximize();
getDriver().navigate().to(appURL);
}
public WebDriver getDriver() {
//Get driver from ThreadLocalMap
return driver.get();
}
@AfterMethod
public void tearDown() {
getDriver().quit();
driver.remove();
}
}
能力工厂类
public class CapabilityFactory {
public Capabilities capabilities;
public Capabilities getCapabilities (String browser, String browser_version, String platform) {
if (browser.equals("chrome"))
capabilities = getChromeOptions(browser_version, platform, browser);
if (browser.equals("firefox"))
capabilities = getFirefoxOptions(browser_version, platform, browser);
if (browser.equals("safari"))
capabilities = getSafariOptions(browser_version, platform, browser);
return capabilities;
}
//Get Chrome Options
public ChromeOptions getChromeOptions(String browser_version, String platform, String browser) {
ChromeOptions options = new ChromeOptions();
/*DesiredCapabilities cap = DesiredCapabilities.chrome();
cap.setCapability("browser_version", browser_version);
cap.setCapability("os", platform);
options.merge(cap);*/
options.setCapability("browserVersion", browser_version);
options.setCapability("platformName", platform);
options.setCapability("browserName", browser);
/*cap.setCapability("os_version", "10");
cap.setCapability("resolution", "1024x768");
cap.setCapability("name", "Bstack-[Java] Sample Test");*/
/*options.addArguments("--start-maximized");
options.addArguments("--ignore-certificate-errors");
options.addArguments("--disable-popup-blocking");*/
//options.addArguments("--incognito");
return options;
}
//Get Firefox Options
public FirefoxOptions getFirefoxOptions(String browser_version, String platform, String browser) {
FirefoxOptions options = new FirefoxOptions();
/*System.setProperty("webdriver.gecko.driver", "/Users/Sasha/Documents/Selenium_projects/testng_maven/SeleniumGrid/src/main/resources/geckodriver");*/
options.setCapability("browserVersion", browser_version);
options.setCapability("platformName", platform);
options.setCapability("browserName", browser);
/*DesiredCapabilities cap = DesiredCapabilities.firefox();
cap.setCapability("browser_version", browser_version);
cap.setCapability("os", platform);
options.merge(cap);*/
/*FirefoxProfile profile = new FirefoxProfile();
//Accept Untrusted Certificates
profile.setAcceptUntrustedCertificates(true);
profile.setAssumeUntrustedCertificateIssuer(false);
//Use No Proxy Settings
profile.setPreference("network.proxy.type", 0);
//Set Firefox profile to capabilities
options.setCapability(FirefoxDriver.PROFILE, profile);*/
return options;
}
public SafariOptions getSafariOptions(String browser_version, String platform, String browser) {
SafariOptions options = new SafariOptions();
options.setCapability("browserVersion", browser_version);
options.setCapability("platformName", platform);
options.setCapability("browserName", browser);
/*FirefoxProfile profile = new FirefoxProfile();
//Accept Untrusted Certificates
profile.setAcceptUntrustedCertificates(true);
profile.setAssumeUntrustedCertificateIssuer(false);
//Use No Proxy Settings
profile.setPreference("network.proxy.type", 0);
//Set Firefox profile to capabilities
options.setCapability(FirefoxDriver.PROFILE, profile);*/
return options;
}
}
FirstTest.class
public class FirstTest extends TestBase {
@Test
public void GOOGLE1() {
System.out.println("Google1 Test Started! " + "Thread Id: " + Thread.currentThread().getId());
getDriver().navigate().to("http://www.google.com");
System.out.println("Google1 Test's Page title is: " + getDriver().getTitle() +" " + "Thread Id: " + Thread.currentThread().getId());
Assert.assertEquals(getDriver().getTitle(), "Google");
System.out.println("Google1 Test Ended! " + "Thread Id: " + Thread.currentThread().getId());
}
@Test
public void GOOGLE2() {
System.out.println("Google2 Test Started! " + "Thread Id: " + Thread.currentThread().getId());
getDriver().navigate().to("http://www.google.com");
System.out.println("Google2 Test's Page title is: " + getDriver().getTitle() +" " + "Thread Id: " + Thread.currentThread().getId());
Assert.assertEquals(getDriver().getTitle(), "Google");
System.out.println("Google2 Test Ended! " + "Thread Id: " + Thread.currentThread().getId());
}
@Test
public void GOOGLE3() {
System.out.println("Google3 Test Started! " + "Thread Id: " + Thread.currentThread().getId());
getDriver().navigate().to("http://www.google.com");
System.out.println("Google3 Test's Page title is: " + getDriver().getTitle() +" " + "Thread Id: " + Thread.currentThread().getId());
Assert.assertEquals(getDriver().getTitle(), "Google");
System.out.println("Google3 Test Ended! " + "Thread Id: " + Thread.currentThread().getId());
}
}
这是我在控制台中得到的:
Chrome_tests started ***
Firefox_tests started ***
Safari_tests started ***
*** Tests GOOGLE1 skipped...
org.openqa.selenium.SessionNotCreatedException: Could not create a session: The Safari instance is already paired with another WebDriver session.
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
remote stacktrace:
Command duration or timeout: 25.97 seconds
Caused by: org.openqa.selenium.SessionNotCreatedException: Could not create a session: The Safari instance is already paired with another WebDriver session.
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
remote stacktrace:
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '10.0.2'
Driver info: driver.version: unknown
org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@1b7d4b97
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
Caused by: org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@1b7d4b97
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '10.0.2'
Driver info: driver.version: unknown
org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@3f5cca9c
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
Caused by: org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@3f5cca9c
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '10.0.2'
Driver info: driver.version: unknown
Sep 11, 2019 7:07:32 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Sep 11, 2019 7:07:32 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
*** Running test method GOOGLE1...
Directory already exists: /Users/Sasha/Documents/Selenium_projects/testng_maven/SeleniumGrid/TestReport
*** Running test method GOOGLE2...
Google2 Test Started! Thread Id: 20
Google1 Test Started! Thread Id: 16
Google2 Test's Page title is: Google Thread Id: 20
Google1 Test's Page title is: Google Thread Id: 16
Google1 Test Ended! Thread Id: 16
*** Executed GOOGLE1 test method successfully...
Google2 Test Ended! Thread Id: 20
*** Executed GOOGLE2 test method successfully...
Sep 11, 2019 7:07:42 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
*** Running test method GOOGLE3...
Google3 Test Started! Thread Id: 20
Google3 Test's Page title is: Google Thread Id: 20
Google3 Test Ended! Thread Id: 20
*** Executed GOOGLE3 test method successfully...
Chrome_tests ending ***
log4j:WARN No appenders could be found for logger (freemarker.cache).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Test ignored.
*** Running test method GOOGLE1...
Test ignored.
*** Running test method GOOGLE2...
*** Tests GOOGLE2 skipped...
Firefox_tests ending ***
Test ignored.
*** Running test method GOOGLE1...
*** Tests GOOGLE1 skipped...
Test ignored.
*** Running test method GOOGLE2...
*** Tests GOOGLE2 skipped...
Safari_tests ending ***
===============================================
Suite
Total tests run: 7, Passes: 3, Failures: 0, Skips: 4
Configuration Failures: 3, Skips: 5
===============================================
Process finished with exit code 0
解决方案
Safari 一次只能处理 1 个浏览器,类似于 IE 和 Edge。Firefox 和 Chrome 应该能够处理更多。从苹果看到这个链接
在任何给定时间只能激活一个 Safari 浏览器实例,并且一次只能将一个 WebDriver 会话附加到浏览器实例。这些约束确保模拟行为(鼠标、键盘、触摸等)准确反映用户在 macOS 窗口环境中可以执行的操作,并防止测试相互竞争窗口和键盘焦点。
推荐阅读
- c# - Asp.Net:使用 ListView 控件创建自定义 CheckBoxList
- python - 触摸底部时pygame无法阻止图像移出屏幕
- django - 从具有多个外键的模型到另一个表的同一列实现group by
- python - 使用 python pandas 从 excel 中确定总运行时间
- c++ - 浮点数和整数之间的不等式比较
- php - Codeigniter无法显示图像
- templates - 具有相同返回类型和相同参数的模板函数
- android - 隐藏 android 默认键盘,因为我在 Kotlin 中有自己的数字键盘
- python - 如何在python中将`UnicodeMultiDict`转换为`MultiDict`
- .net - VB.NET 在 PictureBox 上绘制多条线而不删除以前的更改