我致力于自动化网站,我正在尝试找到一种方法来减少代码中xpath的使用。 我的代码看起来像这样
driver.findElement(By.xpath("//html/body/center/div/div/center/table/tbody/tr/td/form/table/tbody/tr[3]/td/input")).click();
driver.findElement(By.xpath("//html/body/div/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td")).getText();
driver.findElement(By.xpath("//html/body/div/table/tbody/tr/td/div[2]/div/div/div[4]/div/div/div")).click();
driver.findElement(By.xpath("//html/body/div[3]/div/div/div/div[2]/div/span/ul[2]/li[6]/a")).click();
/*driver.findElement(By.xpath("//html/body/div/div/div/div[3]/div/div[2]/div[2]/table/tbody/tr/td[3]/table/tbody/tr/td[2]/em/button")).click();
WebElement editUserForm = driver.findElement(By.cssSelector("iframe[src*='editUserForm']"));
有什么方法可以减少这些xpath,这样我的代码看起来不会破旧吗? 这里的一位成员建议我“请不要使用绝对xpath”。这是什么意思 ? 请帮忙。如果有任何链接可以帮助我,请告诉我。
是否可以创建一个将字符串设置为xpath指针的文件,然后我们可以在代码中使用该字符串?
答案 0 :(得分:11)
你应该投资Page Objects,这是一个非常有用的模式:
https://code.google.com/p/selenium/wiki/PageObjects
它将有助于从实施中分离测试。我的意思是,测试应该留下详细说明采取的步骤,实现(“页面对象”)应详细说明如何采取这些步骤。
对于XPath本身,是的,它们非常糟糕&不可靠的。我会假设您已经通过某些工具(可能是IDE或Firebug)为您自动生成了它们。请把这些扔掉,不要再使用它并阅读一些XPath教程 - 即使XPath规范也是一个很好的学习场所。
首先,丢弃//html/body
位,这是不需要的,并使其看起来更糟。没有它,它会正常工作。
其次,是的,拥有绝对XPath(即基于位置的那些)是不好的。在你的第一个XPath中:
//html/body/center/div/div/center/table/tbody/tr/td/form/table/tbody/tr[3]/td/input
看到最后的tr[3]
?如果我要在那一行前加上另一行(tr
)怎么办?这意味着你的XPath应该是:
//html/body/center/div/div/center/table/tbody/tr/td/form/table/tbody/tr[4]/td/input
所以这意味着测试会破裂。但是,测试不会因为测试的功能被破坏而破坏,因为测试实现被破坏了。你的测试不应该那么脆弱。如果开发人员希望将tr
高于你想要的那个,那很好,除非它打破你正在测试的实际内容,那么你的测试仍然应该通过。
你应该以不同的方式思考它。想想获得该元素的其他方法。假设我有这个:
<div id="divUpload">
<span class="uploadDetails">We only support the following files:
<span class="docSpan">.doc</span>
<span class="txtSpan">.txt</span>
</span>
<button type="submit">Upload the file<submit>
<div>
我希望得到docSpan
作为类名的范围。
我可以:
//div/span/span[1]
哪种方法有效,但如果改为:
<div id="divUpload">
<span class="uploadDetails">We only support the following files:
<span class="excelSpan">.xls</span>
<span class="docSpan">.doc</span>
<span class="txtSpan">.txt</span>
</span>
<button type="submit">Upload the file<submit>
<div>
这意味着[1]
位不再有效。
所以我可以:
//div/span[@class='uploadDetails']/span[text()='.doc']
这意味着,如果我想要的span
成为一个班级uploadDetails
或 {{1}的孩子,那么它只会失败} class完全取消了。
或者我可以:
uploadDetails
这意味着如果跨度完全移动,它只会失败,并且不再是那个'父'div的孩子。
底线是不依赖职位。想想那个元素附近有什么。课上有什么东西吗?里面有文字吗?附近是否有ID?
答案 1 :(得分:0)
这里再次Y XPath Y不使用CSS
css = .uploadDetails&gt; .docSpan - .doc
css = .uploadDetails&gt; .excelSpan - .xls
css = .uploadDetails&gt; .txtSpan - .txt
简单