【发布时间】:2017-08-10 20:13:43
【问题描述】:
我已经看到了很多关于这个主题的问题,但似乎没有一个与我正在寻找的内容有关。我试图在单个类下运行并行方法,使用@BeforeMethod 启动浏览器,@AfterMethod 拆除浏览器。对于这个例子,假设它是一个单一的类文件,里面有几个测试方法。我希望在不同的浏览器中同时运行其中的 4 个。我们正在使用 Groovy,但一个 Java 答案就足够了。
XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="sampleSuite" thread-count="4" preserve-order="true" parallel="methods">
<test name="sample">
<classes>
<class name="tests.some.class.MyClassFile"/>
</classes>
</test>
</suite>
DriverFactory 类,负责简单地创建和返回浏览器:
private static WebDriver createWebDriver() {
String property = System.getProperty("driver", "chrome")
def capabilities
if (property == "chrome") {
capabilities = DesiredCapabilities.chrome()
} else if (property == "firefox") {
System.setProperty("webdriver.gecko.driver", "/usr/local/Cellar/geckodriver/0.16.1/bin/geckodriver")
capabilities = DesiredCapabilities.firefox()
}
def url = System.getProperty("seleniumServerUrl", "http://localhost:4444/wd/hub")
if (!url) {
throw new IllegalStateException("No 'seleniumServerUrl' system property set")
}
def webDriver = new RemoteWebDriver(new URL(url), capabilities)
webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS)
webDriver.manage().window().setSize(new Dimension(1920,1080))
Runtime.addShutdownHook {
try {
webDriver.quit()
} catch (ignore) {}
}
webDriver
}
对于线程,也在 DriverFactory 类中:
static final WebDriver createStackWebDriver(){
ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>(){
protected WebDriver initialValue(){
createWebDriver()
}
}
webDriver.get()
}
现在我有一个 TestPlatform 类,它是架构的核心“设置和拆除”部分。我所有包含 @Test 方法的类文件都扩展了这个 TestPlatform 类:
class TestPlatform {
WebDriver webDriver
@BeforeMethod
void startUpWebBrowser(){
webDriver = DriverFactory.createStackWebDriver()
}
@AfterMethod
void quitWebDriver(){
webDriver.quit()
}
}
当我们运行 XML 文件时,我们看到的是 4 个 startUpWebBrowser() 实例,4 个中的一个会“通过”并继续测试,它会立即打开一个 @987654329 实例中的 4 个方法@,而其他 3 只保持“挂起”。我们需要它在每个 startUpWebBrowser() 实例中打开一个浏览器,而不是在一个实例中打开 4 个浏览器。
我们当前的解决方法是将每个@Test 方法包装在其自己的类中,并将@BeforeMethod 更改为@BeforeClass 以及后面的内容。这在某种程度上可行,但在报告方面非常难看,而且这种方式还有其他一些缺点。
在不对当前架构进行大修的情况下,是否有解决此问题的方法?我只是错过了一些非常简单的东西吗?
【问题讨论】:
-
TestPlatform 中的 webdriver 变量不是线程安全的。将 ThreadLocal 变量作为 static final 移动到 TestPlatform 类中并在 initialValue 方法中调用 DriverFactory.createWebDriver() 会不会更简单。不需要 before 方法,因为您可以在测试方法中的 threadlocal 变量上使用 get() 来获取线程特定的驱动程序。此外,您还有一个用于驱动程序退出方法的关闭挂钩,以及在 aftermethod 中的退出调用。 aftermethod 也可以去掉。
标签: java multithreading selenium-webdriver testng