我看到了很多关于这个主题的问题,但似乎没有一个与我正在寻找的内容相关。我试图在单个类下运行并行方法,使用 @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个中的1个会“通过”并继续测试,它会立即打开4个方法从 startUpWebBrowser()
的一个实例中退出,而其他 3 个实例则保持“挂起”状态。我们需要它在每个 startUpWebBrowser()
实例中打开一个浏览器,而不是在一个实例中打开 4 个浏览器。
我们当前的解决方法是将每个 @Test
方法包装在自己的类中,并将 @BeforeMethod
更改为 @BeforeClass
以及之后的事。这在某种程度上是有效的,但在报告方面非常难看,而且这种方式还有其他一些缺点。
有没有办法在不彻底改变当前架构的情况下解决这个问题?我只是错过了一些非常简单的事情吗?
最佳答案
问题出在您的测试类 TestPlatform
中,其中您将 webdriver 实例变量保存到类级别数据成员 WebDriver webDriver
中。
因此,当两个或多个 @Test
方法并行运行时,所有这些方法实际上都在尝试将 webdriver 实例分配给同一个 webDriver
实例。
请按如下方式修复。
class TestPlatform {
@BeforeMethod
void startUpWebBrowser(){
DriverFactory.createStackWebDriver()
//Access webdriver instances only via DriverFactory.createStackWebDriver()
}
@AfterMethod
void quitWebDriver(){
DriverFactory.createStackWebDriver().quit()
}
}
关于java - 具有并行线程的 TestNG Selenium,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45622741/