問題描述
我正在測試一個(gè)仍在開發(fā)中的網(wǎng)站.
I am testing a website which is still in development.
通常一個(gè)元素的 id、類、文本或在 DOM 中的位置會(huì)改變.然后我一直使用的定位器將無法找到該元素.
Often an element's id, class, text, or position in the DOM will change. And then the locator I've been using will no longer be able to find the element.
但這些功能仍然正常運(yùn)行.當(dāng)沒有實(shí)際回歸時(shí),我不希望多個(gè)測試失敗.
But the features are still functioning properly. I don't want several tests to fail when there is no actual regression.
因此,我沒有為每個(gè)元素使用一個(gè)定位器,而是有一個(gè)定位器集合.
So instead of having a single locator for each element, I have a collection of locators.
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"));
}
我查找元素的方法如下:
My method for finding the element looks like this:
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;
}
它試圖找到集合中第一個(gè)定位器的元素,只有當(dāng)它失敗時(shí),才嘗試下一個(gè)定位器.
It tries to find the element with the first locator in the collection, and only if it fails, try the next locator.
集合是一個(gè) ArrayList
(順序由插入順序定義),這意味著我的 for 循環(huán)
將按照它們添加到列表中的順序嘗試每個(gè)定位器.
The collection is an ArrayList
(order is defined by insertion order), which means my for loop
will try each locator in the order which they were added to the List.
我通過按特定順序添加定位器來初始化上面的列表.id 是第一位的,因?yàn)槲艺J(rèn)為如果元素在 DOM 中的位置發(fā)生變化,但它保留了它的 id,那么這將是我最有可能找到正確元素的方式.Xpath 是最后一個(gè),因?yàn)榧词?id/class/text 發(fā)生了變化,但在 DOM 中該位置仍然存在相同類型的元素,它可能是正確的元素,但可能不如其他定位器那么確定.
I initialized the list above by adding the locators in a particular order. Id is first, because I figure if the element's position in the DOM changes, but it retains its id, then that will be the way I'll be most likely to locate the correct element. Xpath is last because even if the id/class/text changes, but there is still the same type of element in the DOM at that position, it's probably the right element, but maybe less certain than other locators would be.
我正在使用忽略 NoSuchElementException 的流暢等待:
I'm using a fluent wait which ignores 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);
因此,當(dāng)一個(gè)定位器失敗時(shí),它不會(huì)中斷循環(huán) - 它只是記錄失敗,然后繼續(xù)嘗試下一個(gè)定位器.
So when one locator fails, it won't break the loop - it just logs the failure and then still goes on to try the next locator.
如果所有定位器都失敗了,那么元素將保持為空,測試將失敗,原因很可能是特性/功能的實(shí)際回歸.
If all the locators fail, then the element will remain null, the test will fail, and it's far more likely the reason is actual regression of features/functionality.
我會(huì)定期檢查我的日志中是否存在具有 1 或 2 個(gè)失敗定位器的任何元素,同時(shí)在我的 pageObject 中更新它們,同時(shí)測試?yán)^續(xù)順利運(yùn)行.
I periodically check my logs for any element with 1 or 2 failing locators, and update them in my pageObject in the meantime, while tests continue running smoothly.
以這種方式設(shè)置我的項(xiàng)目有什么優(yōu)點(diǎn)或缺點(diǎn)?
What are pros or cons to setting up my project this way?
推薦答案
這是一種有趣的方法,但我擔(dān)心您可能會(huì)掩蓋其他問題.我更愿意與開發(fā)人員更密切地合作,以避免一開始就破壞 UI 問題.
It's an interesting approach, but I'm concerned you might be masking other issues. I'd prefer to work more closely with the developers to avoid breaking UI issues in the first place.
不斷變化的 ID 是動(dòng)態(tài)生成的嗎?如果是這種情況,請(qǐng)查看是否無法在 ID 上獲得后綴,例如 _loginlink.您可能還必須使用從附近的靜態(tài) ID 開始的 XPath://div[@id='login_link_container'/a".(從文檔的根目錄開始,如您的示例所示,這是一個(gè)痛苦的秘訣!:))
Are the changing IDs dynamically produced? If that's the case, look to see if you can't get a suffix on the IDs, something like _loginlink. You might also have to work with an XPath that starts from a nearby static ID: "http://div[@id='login_link_container'/a". (Starting from the root of the document like your example shows is a recipe for pain! :) )
這篇關(guān)于在 Selenium 中為每個(gè)元素使用多個(gè)定位器的優(yōu)缺點(diǎn)?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!