Din*_*ent 8 java testing selenium automated-tests webdriver
我正在测试一个仍在开发中的网站.
DOM中元素的id,类,文本或位置通常会发生变化.然后我一直在使用的定位器将无法再找到该元素.
但功能仍然正常运行.当没有实际的回归时,我不希望几个测试失败.
因此,我没有为每个元素设置一个定位器,而是有一组定位器.
public static final ArrayList<By> LOGIN_ANCHOR_LOCATORS = new ArrayList<By>();
static {
LOGIN_ANCHOR_LOCATORS.add(By.id("loginLink"));
LOGIN_ANCHOR_LOCATORS.add(By.linkText("Login"));
LOGIN_ANCHOR_LOCATORS.add(By.xpath("/html/body/div[5]/a"));
}
Run Code Online (Sandbox Code Playgroud)
我找到元素的方法如下所示:
public WebElement locateElement(ArrayList<By> locators){
// create an element to return
WebElement element = null;
// until the desired element is found...
while (element == null){
// loop through the locators
for (By locator : locators){
// try to find by locator
element = customWait.until(ExpectedConditions.presenceOfElementLocated(locator));
// if not found...
if (element == null){
// log the failure
logFailingLocator(locator);
}
}
}
return element;
}
Run Code Online (Sandbox Code Playgroud)
它尝试在集合中找到具有第一个定位符的元素,并且只有在它失败时,尝试下一个定位器.
该集合是一个ArrayList
(订单由插入顺序定义),这意味着我for loop
将按照它们添加到List中的顺序尝试每个定位器.
我通过按特定顺序添加定位器来初始化上面的列表.Id是第一个,因为我认为元素在DOM中的位置是否会发生变化,但它会保留其id,那么这将是我最有可能找到正确元素的方式.Xpath是最后一个,因为即使id/class/text发生了变化,但是在该位置的DOM中仍然存在相同类型的元素,它可能是正确的元素,但可能不如其他定位器确定.
我正在使用流畅的等待忽略NoSuchElementException:
// Wait 5 seconds for an element to be present on the page, checking
// for its presence once every quarter of a second.
Wait<WebDriver> customWait = new FluentWait<WebDriver>(driver)
.withTimeout(5L, TimeUnit.SECONDS)
.pollingEvery(250L, TimeUnit.MILLISECONDS)
.ignoring(NoSuchElementException.class);
Run Code Online (Sandbox Code Playgroud)
因此,当一个定位器失败时,它不会破坏循环 - 它只记录失败,然后继续尝试下一个定位器.
如果所有定位器都失败,那么该元素将保持为空,测试将失败,并且更可能的原因是特征/功能的实际回归.
我定期检查我的日志中是否有1个或2个失败定位器的元素,并在此期间在我的pageObject中更新它们,同时测试继续顺利运行.
以这种方式设置项目的利弊是什么?
这是一种有趣的方法,但我担心您可能掩盖了其他问题。我更愿意与开发人员更密切地合作,以避免首先出现破坏 UI 的问题。
变化的 ID 是动态生成的吗?如果是这种情况,请查看 ID 上是否无法获取后缀,例如 _loginlink。您可能还需要使用从附近的静态 ID 开始的 XPath:“//div[@id='login_link_container'/a”。(如您的示例所示,从文档的根部开始是一个痛苦的秘诀!:))