我有一个包含3种方法的类的测试套件文件。在套件级别,我给了parallel =“methods”thread-count =“3”,这样就可以为类中的每个方法并行打开3个线程。
执行套件时,会打开3个线程(浏览器)启动URL,但只按照方法中的步骤执行第3个线程/浏览器。对于前2个线程/浏览器没有执行的操作。
尝试了很多寻找这个问题的答案,但找不到解决方案。下面是我使用的代码,如果我错过了什么,请纠正我。
BaseClass的:
public class BaseClass {
public WebDriver driver;
public WebDriverWait wait;
@BeforeMethod()
public void configure() {
System.setProperty("webdriver.chrome.driver","C:\\SeleniumDrivers\\chromedriver.exe");
driver=new ChromeDriver();
driver.get("https://www.google.com");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
@AfterMethod()
public void tearDown() {
driver.quit();
}
}
具有测试方法的类
public class NewTest extends BaseClass{
@Test()
public void method1() {
driver.findElement(By.name("q")).sendKeys("parallel");
driver.findElement(By.name("q")).sendKeys(Keys.ENTER);
}
@Test()
public void method2() {
driver.findElement(By.name("q")).sendKeys("methods");
driver.findElement(By.name("q")).sendKeys(Keys.ENTER);
}
@Test()
public void method3() {
driver.findElement(By.name("q")).sendKeys("testng");
driver.findElement(By.name("q")).sendKeys(Keys.ENTER);
}
}
套件文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="methods">
<test thread-count="5" name="Test">
<classes>
<class name="website.NewTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
预期结果:3个浏览器并行打开。第一个浏览器应搜索“并行”。第二个浏览器应该搜索“方法”。第三个浏览器应搜索“自动化”。
实际结果:3个浏览器并行打开,但首先打开的2个浏览器按照方法执行操作,最后一个浏览器打开搜索单词“parallelmethodtestng”并关闭。打开的前2个浏览器不会根据代码关闭最大化。
===============================================
Suite
Total tests run: 3, Failures: 2, Skips: 0
===============================================
希望这可以帮助。
WebDriver不是线程安全的。我可以引用Selenium FAQ
问:WebDriver是否是线程安全的? 答:WebDriver不是线程安全的。话虽如此,如果您可以序列化对底层驱动程序实例的访问,则可以在多个线程中共享引用。这是不可取的。另一方面,您/可以为每个线程实例化一个WebDriver实例。
如果您的解决方案用于大型或小型项目,则无关紧要。如果要扩展解决方案,可以始终使用Selenium网格进行并行执行。本地WebDriver对象不是您的问题。分析内存吃Chrome实例将是你的问题。
我建议使用qaf TestNG extension,它负责驱动程序管理,资源管理等等,用于Web,移动和Web服务功能测试自动化。使用qaf,您的测试类可能如下所示:
public class NewTest extends WebDriverTestCase{
@Test()
public void method1() {
getDriver().get("https://www.google.com");
getDriver().findElement(By.name("q")).sendKeys("parallel");
getDriver().findElement(By.name("q")).sendKeys(Keys.ENTER);
}
@Test()
public void method2() {
getDriver().get("https://www.google.com");
//another improved way
WebElement ele = getDriver().findElement(By.name("q"));
ele.sendKeys("methods");
ele.sendKeys.submit();
}
@Test()
public void method3() {
getDriver().get("https://www.google.com");
//another way with qaf
WebElement ele = $("name=q");
ele.sendKeys("testng");
ele.sendKeys.submit();
}
}
使用内置数据提供程序,您还可以使用make test data-driven。
如果你想在没有任何扩展名的情况下只使用TestNG,你需要通过ThreadLocal处理webdriver
private final ThreadLocal<WebDriver> driver = new ThreadLocal<>();
应通过同步方法创建驱动程序。
public synchronized WebDriver createDriver() {
return new ChromeDriver(options.getOptions());
}
@BeforeMethod(alwaysRun = true)
public void setupDriver(String browser) {
driver.set(CcreateDriver());
}
public synchronized WebDriver getDriver() {
return driver.get();
}
您还需要记住使用线程安全映射,列表等,如concurentHashMap等。它也适用于Selenium Grid。所以ThreadLocal也应该应用于RemoteWebDriver,因为它也不是线程安全的。
这可能发生在thread-count
不在正确的地方。根据TestNG文档,qazxswpo应该是套件标签。请按照下面的说明使用它。
thread-count
在这里检查testng文档:
<suite name="My suite" parallel="methods" thread-count="5">