在 Selenium 中为每个元素使用多个定位器的优缺点?
Posted
技术标签:
【中文标题】在 Selenium 中为每个元素使用多个定位器的优缺点?【英文标题】:Pros/cons for using multiple locators per element in Selenium? 【发布时间】:2013-06-02 21:57:25 【问题描述】:我正在测试一个仍在开发中的网站。
通常一个元素的 id、类、文本或在 DOM 中的位置会改变。然后我一直使用的定位器将无法找到该元素。
但这些功能仍然正常运行。当没有实际回归时,我不希望多个测试失败。
因此,我没有为每个元素使用一个定位器,而是有一个定位器集合。
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"));
我查找元素的方法如下:
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;
它试图找到集合中第一个定位器的元素,只有当它失败时,才尝试下一个定位器。
集合是一个ArrayList
(顺序由插入顺序定义),这意味着我的for loop
将按照它们添加到列表中的顺序尝试每个定位器。
我通过按特定顺序添加定位器来初始化上面的列表。 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);
因此,当一个定位器失败时,它不会中断循环 - 它只是记录失败,然后继续尝试下一个定位器。
如果所有定位器都失败了,那么元素将保持为空,测试将失败,更可能的原因是特性/功能的实际回归。
我会定期检查我的日志中是否存在具有 1 或 2 个失败定位器的任何元素,同时在我的 pageObject 中更新它们,同时测试继续顺利运行。
以这种方式设置我的项目有什么优点或缺点?
【问题讨论】:
很好的问题,帕特!在我的工作中,我们使用@FindBy。您是否考虑过将其作为替代方案?示例:@FindBy(className="reducedPrice") private List<WebElement> reducedPrice;
.
【参考方案1】:
这是一种有趣的方法,但我担心您可能会掩盖其他问题。我更愿意与开发人员更密切地合作,以避免一开始就破坏 UI 问题。
不断变化的 ID 是动态生成的吗?如果是这种情况,请查看是否无法在 ID 上获得后缀,例如 _loginlink。您可能还必须使用从附近的静态 ID 开始的 XPath:“//div[@id='login_link_container'/a”。 (从文档的根目录开始,如您的示例所示,这是一个痛苦的秘诀!:))
【讨论】:
赞成 - 我同意,与开发人员更密切地合作将是理想的选择。不幸的是,我与他们没有联系。它们是完全独立的多个供应商。我使用 XPath 的完整路径的原因是因为我认为 id 在我的情况下比元素在 DOM 中的位置更可能发生变化,所以我只是避免在 XPath 中使用 ID 以最大限度地提高健壮性,而不是依赖于其他更改元素以保留其 ID。以上是关于在 Selenium 中为每个元素使用多个定位器的优缺点?的主要内容,如果未能解决你的问题,请参考以下文章