Java Selenium Web驱动程序并行执行测试用例时的过时元素引用异常
这是我的类,其中包含我希望并行执行的测试方法f()。数据提供者向测试方法提供输入Java Selenium Web驱动程序并行执行测试用例时的过时元素引用异常,java,selenium-webdriver,testng-dataprovider,Java,Selenium Webdriver,Testng Dataprovider,这是我的类,其中包含我希望并行执行的测试方法f()。数据提供者向测试方法提供输入 public class DemoTest { private WebDriver driver; @Test(dataProvider = "dp") public void f(Integer n, String s) { try { driver.get("www.google.com"); driver.findElement(By.id("lst-ib")).sendKeys("12345
public class DemoTest {
private WebDriver driver;
@Test(dataProvider = "dp")
public void f(Integer n, String s) {
try {
driver.get("www.google.com");
driver.findElement(By.id("lst-ib")).sendKeys("1234567");
System.out.println("method f id:"+Thread.currentThread().getId()+" n:"+n+" s:"+s);
}
catch(Exception e) {
e.printStackTrace();
}
}
@BeforeSuite
public void beforeMethod() {
try {
driver= new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
System.out.println("Before method id:"+Thread.currentThread().getId());
}
catch (Exception e) {
e.printStackTrace();
}
}
@AfterSuite
public void afterMethod() {
try {
System.out.println("After method id:"+Thread.currentThread().getId());
if(driver != null ) {
driver.quit();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
@DataProvider(parallel=true)
public Object[][] dp() {
return new Object[][] {
new Object[] { 1, "a" },
new Object[] { 2, "b" },
new Object[] { 3, "c" },
new Object[] { 4, "d" },
};
}
}
这是testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite" parallel="methods" data-provider-thread-count="2">
<test name="prelogin">
<classes>
<class name="com.package.DemoTest"></class>
</classes>
</test>
</suite>
我想在两个线程中并行执行test f()。
对于findElement方法的一次迭代,我得到了陈旧的元素引用异常。
有谁能告诉我要添加到这个代码段中的内容吗?请将您的数据提供者的名称包括在内 这应该是这样的,
@DataProvider(name = "dp" , parallel=true)
public Object[][] dp() {
return new Object[][] {
new Object[] { 1, "a" },
new Object[] { 2, "b" },
new Object[] { 3, "c" },
new Object[] { 4, "d" },
};
}
还有你的司机,应该是
driver.get("https://www.google.co.in");
最后是你的问题
如果在您最初找到元素
后对页面进行了任何更改,那么webdriver引用现在将包含一个过时的
引用。由于页面已更改,元素将不再位于webdriver
期望的位置
要解决您的问题,请尝试在每次需要使用元素时找到它——编写一个小方法,您可以在适当的时候调用它
private void clickAnElementByLinkText(String id) {
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(By.id(id)));
driver.findElement(By.id(id)).sendKeys("1234567");
}
@Test(dataProvider = "dp")
public void f(Integer n, String s) {
try {
driver.get("https://www.google.co.in");
clickAnElementByLinkText("lst-ib");
System.out.println("method f id:"+Thread.currentThread().getId()+" n:"+n+" s:"+s);
}
catch(Exception e) {
e.printStackTrace();
}
}
现在您不会看到过时的元素引用异常,这是由两个独立测试使用一个
WebDriver
实例引起的。在@BeforeMethod
中,您正在通过driver=new FirefoxDriver()创建一个新实例代码>,但这将替换该字段
private WebDriver driver;
通过这个例子。每个线程都创建了一个新实例,但只使用最后一个实例,private WebDriver
字段当前引用的实例。您需要告诉每个测试方法保留单独的WebDriver实例,而不将其用作类字段
当Webdriver注意到页面上的某些内容已更改时,将引发StaleElementReference
异常。在您的情况下会发生这种情况,因为当时另一个线程正在使用同一个WebDriver。为什么只有在并行执行方法时才会出现过时的元素引用异常?这不是在并行执行时发生的,您是否尝试过不并行执行?Google.com被加载了四次[4次来自数据提供程序的输入],因此元素将不再是webdriver期望的位置。是的,我没有并行执行,所以我从来没有得到过此异常是由于每个线程使用相同的web驱动程序实例而导致的此异常吗?您已经询问了陈旧的元素引用异常,在您最初找到元素后,当页面发生任何更改时,就会发生这种情况。所以我提供了解决方案,如果我有10个或更多的测试并行运行,该怎么办?我理解为什么会有例外,但我不知道如何解决this@Prozorov如果您想并行运行这些测试,您必须为每个线程创建一个新的WebDriver实例并跟踪它们。原始代码不起作用,因为新实例总是替换私有WebDriver
,但是如果您只是为它们创建十个变量,例如webdriver1
到webdriver10
,那么问题就应该解决了。只要记住使用synchronized
关键字,你需要在每个线程中执行可见的操作。不,不要为同一个属性创建10个不同的变量,这绝对不是一个干净的代码,相反,我只使用了1个驱动程序->当你运行测试时,每个线程都有自己的webdriver,您可以在pom或gradle文件测试中指定{systemProperty(“junit.jupiter.execution.parallel.enabled”,true)systemProperty(“junit.jupiter.execution.parallel.mode.default”,“CONCURRENT”)}