如何避免空额外浏览器中打开使用TestNG运行并行测试时 [英] How to avoid empty extra browser opens when running parallel tests with TestNG
问题描述
虽然我正在使用TestNG和硒的webdriver并行测试的情况下,也有开空,甚至在执行完成后不关闭一些浏览器实例。我已阅读不同的论坛上问类似的问题,几个主题,但他们都不似乎是同样的问题。
While I'm running parallel test cases using TestNG and selenium-webdriver, there are some browser instances that open empty and doesn't close even after the execution finish. I have read several topics on different forums asking about similar problems but none of them seems to be the same issue.
也似乎更加空虚的浏览器是开放的,当我添加更多的测试套件。我不知道以下信息会有什么相关的这个问题,但我会尽量提供什么,我有一个完整的画面:
Also seems like more empty browsers are open when I add more test to the suite. I'm not sure what of the following information will be relevant for this problem but I will try to provide a complete picture of what I have:
- 我使用的(如前所述)TestNG的 - 的webdriver
- 我与页面对象的工作模式。
- 我是从一个JavaFX接口,允许用户选择一些选项,运行自动化的我。
- 我使用ChromeDriver模拟移动设备上。
- 我使用的驱动程序,允许我使用独占静态驱动程序为每个测试的本地线程。
- 没有空的浏览器打开的时候,我不并行运行。
这是我的testng.xml:
This is my TestNg.xml:
<suite name="Suite" parallel="classes" thread-count="4">
<test name="Test">
<groups>
<run>
<!-- Use include to specify what you want to run or exclude to not run the mentioned group(s) -->
<include name="fullRegression"/>
<exclude name="brokenOrDevelopment"/>
</run>
</groups>
<packages>
<!-- Packages who contains the test cases classes -->
<package name="Test"/>
</packages>
这是创建驱动程序实例类
This is the class which create the driver instance
public class TestCaseConfiguration {
protected HomePageObjects homePage = null;
protected DesiredCapabilities capabilities;
protected ExtentReports REPORTMANAGER;
protected ExtentTest REPORT;
public static ThreadLocal<ChromeDriver> driver;
@BeforeMethod(alwaysRun = true)
public void setup() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "src/Tools/chromedriver.exe");//chrome driver version 2.20 | We need to have a relative path since no all the user will have the driver on C:
capabilities = DesiredCapabilities.chrome();
Map<String, String> mobileEmulation = new HashMap<String, String>();
mobileEmulation.put("deviceName", Constants.DEVICE);
Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
/**
* dirver is a ThreadLocal<ChromeDriver>. This allows the driver to be static and available for the complete project, and exclusive for each thread.
*/
driver=new ThreadLocal<ChromeDriver>()
{
@Override
protected ChromeDriver initialValue()
{
return new ChromeDriver(capabilities);
}
};
driver.get().manage().deleteAllCookies();
driver.get().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get().navigate().to(Constants.DOMAIN);
homePage = PageFactory.initElements(driver.get(), HomePageObjects.class);
}
@AfterMethod(alwaysRun = true)
public void close() throws InterruptedException {
driver.get().close();
driver.get().quit();
}
}
本类每个测试用例类扩展。如预期运行测试,唯一的问题似乎是多余的浏览器实例。
This class is extended by each test case class. The tests run as expected, the only problem seems to be the extra browser instances.
难道没有人知道如何避免这个问题,或者如果我做错了什么?
感谢您的帮助。
Doesn't anyone know how can I avoid that issue or if I'm doing something wrong? Thanks for the help.
推荐答案
您正在创建一个新的的ThreadLocal&LT; ChromeDriver&GT;
实例,并重新分配驱动
每次设置
运行。想象一下下面的场景,其中设置
是并行多线程名为:
You are creating a new ThreadLocal<ChromeDriver>
instance and reassigning driver
each time setup
runs. Imagine the following scenario where setup
is called in parallel by multiple threads:
- Thread0创建
的ThreadLocal&LT; ChromeDriver&GT;
实例,其分配给驱动
,并呼吁driver.get()
。一个浏览器现已开放。 - 线程1创建
的ThreadLocal&LT; ChromeDriver&GT;
实例,其分配给驱动
(更换一个接分配给它Thread0),并要求driver.get()
。两个浏览器现在是开放的,每个的ThreadLocal
实例之一。 - Thread0调用
driver.get()
再度但驱动
不再引用相同的ThreadLocal的
实例,这样一个新的浏览器中打开。三种浏览器现在是开放的,一个是孤立的ThreadLocal
实例和两个在引用的ThreadLocal
。
- Thread0 creates a
ThreadLocal<ChromeDriver>
instance, assigns it todriver
, and callsdriver.get()
. One browser is now open. - Thread1 creates a
ThreadLocal<ChromeDriver>
instance, assigns it todriver
(replacing the one assigned to it by Thread0), and callsdriver.get()
. Two browsers are now open, one perThreadLocal
instance. - Thread0 calls
driver.get()
again butdriver
no longer references the sameThreadLocal
instance so a new browser is opened. Three browsers are now open, one in an "orphaned"ThreadLocal
instance and two in the referencedThreadLocal
.
现在想象的场景,但有两个以上的线程!您将有大量的孤儿的ThreadLocal
实例左右浮动,其中一些具有一些相关的 ChromeDriver
实例螺纹(S),但要引用任何线程没有对象的的ThreadLocal
以让出来。
Now imagine that scenario but with more than two threads! You'll have lots of "orphaned" ThreadLocal
instances floating around, some of which having a ChromeDriver
instance associated with some thread(s) but no objects on any threads with references to the ThreadLocal
in order to "get" them.
要解决,我建议标记问题驱动
为最后
并分配 ThreadLocal的
实例来一次。
To fix the problem I recommend marking driver
as final
and assigning a ThreadLocal
instance to it once.
例如
public class TestCaseConfiguration {
protected HomePageObjects homePage = null;
protected ExtentReports REPORTMANAGER;
protected ExtentTest REPORT;
public static final ThreadLocal<ChromeDriver> driver;
private static final Set<ChromeDriver> drivers = Collections.newSetFromMap(new ConcurrentHashMap<>());
static {
System.setProperty("webdriver.chrome.driver", "src/Tools/chromedriver.exe");//chrome driver version 2.20 | We need to have a relative path since no all the user will have the driver on C:
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
Map<String, String> mobileEmulation = new HashMap<String, String>();
mobileEmulation.put("deviceName", Constants.DEVICE);
Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
/**
* dirver is a ThreadLocal<ChromeDriver>. This allows the driver to be static and available for the complete project, and exclusive for each thread.
*/
driver = new ThreadLocal<ChromeDriver>() {
@Override
protected ChromeDriver initialValue() {
ChromeDriver chromeDriver = new ChromeDriver(capabilities);
drivers.add(chromeDriver);
return chromeDriver;
}
};
}
@BeforeMethod(alwaysRun = true)
public void setup() throws InterruptedException {
driver.get().manage().deleteAllCookies();
driver.get().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get().navigate().to(Constants.DOMAIN);
homePage = PageFactory.initElements(driver.get(), HomePageObjects.class);
}
@AfterSuite(alwaysRun = true)
public void close() throws InterruptedException {
for (ChromeDriver chromeDriver : drivers) {
try {
chromeDriver.quit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
这篇关于如何避免空额外浏览器中打开使用TestNG运行并行测试时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!