java - Selenium,TestNg 并行运行未按预期工作
问题描述
我有 3 个测试类,其中包含多个要并行运行的测试方法。我正在使用 ThreadLocal 来隔离每个线程的 webdriver 实例。当我以顺序方式运行测试时,一切看起来都很好,但是当我并行运行它们时会出现问题。下面是我的套件文件
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="platform" parallel="classes" thread-count="5">
<test name="platform">
<classes>
<class name="com.sat.platform.mobile.PlatformMobileIdCaptureMonitoringWf11"></class>
<class name="com.sat.platform.mobile.PlatformMobileIdVerificationMonitoringWf2"></class>
<class name="com.sat.platform.mobile.PlatformMobileIdandIVMonitoringWf3"></class>
<class name="com.sat.platform.mobile.PlatformMobileLivenessMonitoringWf6"></class>
<class name="com.sat.platform.mixed.PlatformMixedIdSimilarityMonitoringWf2and5"></class>
</classes>
</test>
</suite>
我在BrowserClient.java的 @BeforeClass 中初始化 Webdriver,如下所示。
protected WebDriver driver;
private static int implicitWaitTime;
private static int explicitWaitTime;
private static int fluentWaitTime;
private static int pollingTime;
protected static WebDriverWait explicitWait;
protected static Wait<WebDriver> fluentWait;
private static String browser;
protected static Browsers browsers;
static {
Properties prop = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream("browser.properties");
try {
prop.load(stream);
} catch (IOException e) {
}
implicitWaitTime = Integer.parseInt(prop.getProperty("browser.implicit.wait.timeout"));
explicitWaitTime = Integer.parseInt(prop.getProperty("browser.explicit.wait.timeout"));
fluentWaitTime = Integer.parseInt(prop.getProperty("browser.fluent.wait.timeout"));
pollingTime = Integer.parseInt(prop.getProperty("browser.wait.polling.time"));
browser = System.getProperty("browser");
}
@BeforeClass
public void initializeEnv() throws MalformedURLException {
driver = BrowserFactory.createInstance(browser, implicitWaitTime);
DriverFactory.getInstance().setDriver(driver);
driver = DriverFactory.getInstance().getDriver();
explicitWait = new WebDriverWait(driver, explicitWaitTime);
fluentWait = new FluentWait(driver).withTimeout(Duration.of(fluentWaitTime, SECONDS))
.pollingEvery(Duration.of(pollingTime, SECONDS))
.ignoring(NoSuchElementException.class);
}
这里使用的类,即 BrowserFactory.java
public static WebDriver createInstance(String browser, int implicitWaitTime) throws MalformedURLException {
WebDriver driver = null;
Browsers browserEnum = Browsers.valueOf(browser);
String testVideo = ImageProcessingUtils.getAbsolutePath("digital_copy.mjpeg", false);
switch (browserEnum) {
case chrome:
ChromeOptions options = new ChromeOptions();
options.addArguments("--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream",
"--use-file-for-fake-video-capture=" + testVideo, "--start-maximized");
driver = new ChromeDriver(options);
break;
case firefox:
FirefoxProfile firefoxProfile = new FirefoxProfile();
firefoxProfile.setPreference("media.navigator.permission.disabled", true);
firefoxProfile.setPreference("media.navigator.streams.fake", true);
firefoxProfile .setPreference("browser.private.browsing.autostart", false);
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setProfile(firefoxProfile);
driver = new FirefoxDriver(firefoxOptions);
break;
}
}
DriverFactory.java
public class DriverFactory {
private static DriverFactory instance = new DriverFactory();
private static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
private static List<WebDriver> driversList = new ArrayList();
private DriverFactory(){
}
public static DriverFactory getInstance() {
return instance;
}
public WebDriver getDriver(){
WebDriver localDriver = driver.get();
driversList.add(localDriver);
return localDriver;
}
public void setDriver(WebDriver driver){
this.driver.set(driver);
}
public static void removeDriver(){
for(WebDriver driver : driversList) {
driver.quit();
}
}
}
我的测试类扩展了 BrowserClient.java,我可以直接使用驱动程序。所有 3 个测试类中的常用方法之一是Mercer_gets_oauth_token(),如下所示。问题是当测试套件运行时,3 个 firefox 浏览器并行打开,它们都导航到登录页面,但只有 1 个,有时 2 个测试通过,而第 3 个测试失败(无法登录)。
@Test
public void merchant_gets_oauth_token() {
OAuth2Client client = new OAuth2Client();
String loginUrl = DslConfigFactory.getEnvConfig("portal.customer.url");
driver.get(loginUrl);
CustomerPortalLoginPage loginPage = new CustomerPortalLoginPage(driver);
log.info("----------merchant logging to customer portal to get oauth token----------");
loginPage.login(merchantUser.getEmail(), merchantUser.getPassword());
CustomerPortalHomePage homePage = new CustomerPortalHomePage(driver);
homePage.clickOnSettings();
CustomerPortalSettingsPage settingsPage = new CustomerPortalSettingsPage(driver);
settingsPage.clickOnApiCredentials();
CustomerPortalApiCredentialsPage apiCredentialsPage = new CustomerPortalApiCredentialsPage(driver);
clientCredentials = apiCredentialsPage.getOauth2ClientCredentials();
oauthToken = client.getOauthToken(clientCredentials.get("token"), clientCredentials.get("secret"));
}
我一直在努力解决这个问题,并且在没有帮助的情况下查找了很多在线资源。也许这里有人能够做RCA。提前致谢!!
解决方案
public static void removeDriver(){
for(WebDriver driver : driversList) {
driver.quit();
}
}
Here, replace driver.quit() with driver.close().
driver.close() method it will close only current driver. driver.close() closes all drivers.
When first instance executes removeDriver(), it will closes all windows/drivers. Then next instance try to execute removeDriver(),there driver is not available because it is already closed by previous instance of driver.so you get error.
推荐阅读
- python - Django - Why is this Model not creating a pk and complaining about the integrity of the pk of a related model?
- python - Predict classes or class probabilities?
- python - numpy 3d array: normalising columns in the last dimension while filtering specific rows in the last dimension
- python-3.x - 使用 Numpy 挂在 qsub 中的 multiprocessing.Pool()
- python - python中的UVa 11450-dp
- chef-infra - 使用版本标签在厨师中进行符号链接
- json - 将 JSON 结构转换为管道格式
- asp.net - ASP C# - 注销操作重定向不起作用
- python - Groupby nunique 与独特的分类数据
- java - Java“AWT-EventQueue-0”java.lang.NullPointerException