为Web元素创建最终XPath的20种最佳方法

发表于:2019-7-19 09:53

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:桃子    来源:51Testing软件测试网原创

  使用于任何Web元素类型的XPATH定位的前20种方法(XPATH永远不会无效):
  Web应用程序由不同类型的Web元素组成,例如用于单击按钮Web元素,输入以键入文本的Web元素,下拉列表,单选按钮等。
  这些Web元素也称为标记或节点。
  在自动化Web应用程序时,首先要编写一个自动化脚本,该脚本将找到Web元素,对其执行操作,例如,单击按钮,在输入框中输入文本,选择复选框,选择单选按钮,向上或向下滚动,最后验证操作的预期行为
  找到一个元素就像在地图上找到某人的房子一样。我们在没有任何外部帮助的情况下找到朋友家的唯一方法就是我们应该有一张地图并知道要找什么(房子)。
  在我们的案例中,地图就好像DOM(HTML标签,JavaScript等),其中存在所有Web元素,以及我们想要查找的特定Web元素都在地图里
  找到元素的唯一地址或路径后,自动化脚本将根据测试场景对其执行某些操作。例如,您要验证单击按钮后打开的页面的URL地址是否正确
  但是,找到Web元素的唯一地址/路径并不能成功验证,因为可能存在类似的标记,相同的属性值,相同的路径,因为很难为称为“XPATH”的Web元素创建精确的唯一地址。
  在这里,我们将深入探讨一些非常有效的技术,为任何类型的Web元素生成有效且独特的XPATH
  有时您可以使用浏览器扩展轻松创建XPath,但在我的自动化测试职业生涯中,我遇到了无数传统浏览器扩展无法工作的情况,您必须使用自己的创造力来提出自己的自定义XPath。我确信你已经或将面临类似的情况。
  在本教程中,我们将介绍如何为Web元素创建最终XPath的20种最佳方法,即使代码更改后,XPath将始终保持有效(除非开发人员重写整个特征/模块)。
  通过了解所有这些技术,您将成为编写自己的XPath的大师,并且能够编写杀手级XPath,几乎没有机会变得无效。
  首先,让我们首先理解XPath语法并定义其每个部分
  XPath的外观以及每个部分的描述
  //:选择当前节点,例如input,div等。
  标记名:Web元素/节点的标记名
  @:选择属性
  属性:节点/特定Web元素的属性名称
  值:属性的值
  在这里分享一些技巧,80%的时间我的自动化测试脚本因XPath而失败。这是由于提供的XPath或XPath有多个Web元素无效或页面尚未加载。
  因此,只要您的测试用例失败:
  1、复制你的XPath。
  2、在DOM中的浏览器(F12或开发人员工具窗口)中搜索它以验证它是否有效(参见下图)。
  专业提示1:确保路径是唯一的,在DOM中搜索两次时,不会出现其他网络元素。
  专业提示2:有时会出现计时问题,这意味着在脚本查找时您的网页元素/页面尚未加载,因此会增加一些等待时间并重新测试。
  专业提示3:可以在搜索Web元素之前打印整个DOM,这样,可以通过查看控制台来判断您的Web元素是否存在于DOM中。
  在我们深入研究XPath之前,如果您可以直接访问开发团队,或者您的团队位于您所在的位置,那么请您的开发团队为您提供唯一的ID每个web元素或至少是您要用于Automation的元素,这将节省您的大量时间。
  如果这种可能性无法实现,那么您可能需要使用您的创造力并提出自己的定制XPath,这就是我们现在要学习的内容。
  1)反向查找
  假设你想点击一个按钮,就会有一个类似的按钮。两个按钮都具有id属性,但它们是动态的,并且两个按钮元素中的属性都不是唯一的。
  在下面的场景中,我们要点击“Test Interactive”的“Setting”按钮。
  代码如下:
  如果查看“设置”按钮,则两个代码都相似。通过使用传统方式,例如id,name,value,contains等,它们都不会起作用。
  // * [contains(text(),'Setting')],这将产生两个web元素。因此它并不是唯一的。
  所以这是最终战略,
  >>首先,找到最接近的唯一标签,在这种情况下,它是<widget id ='rcTest'.........>
  >>其次,找到最接近预期的Web元素的Web元素,在本例中包含(text(),'TEST Interactive')。现在我们在<DIV>中存在'Setting'按钮但是要点击它,我们首先需要使用双点转到主<DIV>,如下所示。

  >>如您所见,我们处于<DIV>级别,其中第二个Web元素为“设置”按钮。这个<DIV>有两个按钮,我们想要转到第二个按钮,即“设置”按钮。通过在末尾添加'/ button [2]',我们可以为“设置”按钮获取我们独特的XPATH,如下所示
  最终XPATH:
  如果您认为他们可能会将Web元素类型从“按钮”更改为其他内容,那么这是另一种生成方式。
 “// * [@ id ='rcTEST'] // * [contains(text(),'TEST Interactive')] /..//* [contains(text(),'Setting')]”
  或使用“跟随兄弟”
  2)使用变量和自定义值
  假设有一个Web应用程序具有上传/下载文件的FTP(“文件传输协议”)功能,您可以通过单击下载链接下载特定文件的测试用例。
  首先,我们可以将我们要查找的文件名定义为变量。
 String expectedfileName =“Test1”;
   现在使用XPATH我们可以找到实际的文件名
  在上面的XPath中,...'/ tr / td [1] .getAttribute(“title”)'将转到特定的行和第一列,并获取title属性的值。我们可以将实际文件名存储到另一个变量中。
  一旦我们同时拥有预期文件名和实际文件名,我们就可以比较两者,如果两者都匹配,我们只需单击其下载链接即可
  我们还可以在每行中创建一个循环并继续验证文件名,直到找到它为止。
  3)使用“XML”标签,“AND”等
  我们可以使用自定义标签生成唯一的XPATH并添加其他条件。
  例如,假设我们的主要Web元素存在于主<address>标记中,并且有多个地址标记,但您只想查找特定的地址标记。所有地址标签都有一个类属性,因此我们可以从中开始。
  我们注意到我们的Web元素位于<DIV>标记中,其中包含一些名为“Testing”的文本。
  我们发现结果有多个web元素。因此,为了使它更独特,我们可以添加其他条件,例如“id”,它最终将我们指向我们正在寻找的web元素。
  4)使用属性和表XPATH
  假设我们想要键入放置在表中的Web元素,并将表放在表单元素中。
  我们可以在DOM中找到名为“myForm”的所有表单。
  现在在所有表单中找到id为'tbl_testdm'的表。
  在表格中,转到特定的行和列。
  在单元格内,如果有多个输入,则找到一个输入,其中value ='Open RFS',这将为我们提供该字段的最终XPath。
  5)使用属性,表和文本
  假设您的Web元素位于Panel Table中,并且有一些常用文本。
  首先从具有唯一属性的面板开始,在这种情况下是'TITLE'。
  现在浏览所有表标签。
  在所有表中找到包含文本“作者”的列。
  最终的XPath将是:
  6)使用嵌套属性生成XPATH
  也可以使用嵌套属性生成目标Web元素的XPath。例如,在这种情况下,它将在DOM中查找特定属性,然后在其中查找另一个属性。
  7)通过组合属性,分区和按钮生成XPath
  例如,在下面的XPath中,我能够通过使用id(相对XPath),一些div标签和一个按钮来找到目标web元素。
  8)XPATH使用CONTAINS,REVERSE LOOKUP等生成
  一旦我有一个没有直接识别的下拉菜单。我不得不使用CONTAINS,REVERSE,DIVs属性来提出最终的XPATH,如下所示。
  9)使用Relative,CONTAINS,REVERSE,FOLLOWING SIBLING等生成XPath。
  我遇到了应用程序显示图形的情况,每个图形值都必须经过验证。但是,遗憾的是,每个值都没有任何唯一标识,因此我提出了最终的XPATH,如下图所示,其中包含一个图形值,它结合了相对,包含,反向,跟随兄弟和div标记
  10)使用Attributes,Contains,Reverse,Preceding-Sibling,Divs和Span生成XPath
  11)使用属性,XML标签等。
  在下面的XPATH,属性和XML标记中,序列用于提供Web元素的最终唯一地址。
  12)通过不查看整个页面而是查看所有链接并包含而生成XPath
  下面的XPath将仅查找整个页面中包含“参数数据手动输入”文本的链接。
  13)使用包含和属性
  14)使用属性,遵循兄弟姐妹和后代
  15)使用属性,遵循兄弟,后代和文本
  16)使用标题和文本
  如果web元素是包含某些特定文本的标题,则XPath可能如下所示:
  17)使用标题文本,兄弟姐妹,路径等
  18)使用属性,包含和前置兄弟姐妹
  19)通过使用Id属性,一些特定文本和反向查找来查找下拉列表
  20)组合“Id”属性并查找具有特定文本的链接
  结论
  在编写杀手级XPATH时,它实际上取决于您对代码的理解和分析。您对代码的理解越多,您在编写有效XPATH时可以找到的方式就越多。
  编写XPath的第一步是找到与您的目标Web元素最接近的唯一Web元素,并使用上面讨论的不同技术(如属性,DIV,跟随,包含等)保持接近。
  最后,我们再次这样说,如果您要求开发团队在您感兴趣的所有Web元素中添加唯一ID,那么它将真正让您的生活更轻松。
  每当sprint周期或新需求开始工作并且团队与新模型共享时,我总是会经历所有模拟并考虑潜在的自动化测试案例,准备一份将使用的所有潜在Web元素的列表在自动化测试和准备我自己的ID。
  一旦完成了所有Web元素的列表以及我建议的ID,我将事先将其分享给开发人员以用于开发代码。通过这种方式,我可以通过简化XPATH编写战斗来获得唯一的ID。
  下面是编写XPATH的不同方法的组合列表:
   “//*[@id='rcTEST']//*[contains(text(), ‘TEST Interactive')]/../button[2]”
  “//*[@id='rcTEST']//*[contains(text(), ‘TEST Interactive')]/..//*[contains(text(), ‘Setting')]”
  “//*[@id='rcTEST']//*[contains(text(), ‘TEST Interactive')]/following-sibling::button”
  “String actualFileName = WebDriverAccess.getDriver().findElement(By.xpath(“//*”+fileName +”/tr/td[1]”)).getAttribute(“title”);”
  WebDriverAccess.getDriver().findElement(By.xpath(“//*”+fileName +”/tr/td[4]”)).click();
  “// address[@class='ng-scope ng-isolate-scope']//div[contains(.,Testing') and @id='msgTitle']”
  “//*[@name='myForm']//table[@id='tbl_ testdm’]/tbody/tr/td[6]/
  input[@value='Open RFS']”
  “//*[@title=’Songs List Applet']//table//td[contains(text(),'Author')]”
  “//*[@id='parameters']//*[@id='testUpdateTime']”)”
  “//*[@id='MODEL/PLAN']/div[1]/div[2]/div[1]/div[1]/widget/section/div[1]/div/div[1]/div/div/button[1]”
  “//*[contains(text(),'Watch Dial)]/../div/select[@data-ng-model='context.questions[subqts.subHandleSubId]']”),”
  “//*[@id='RESEARCH/PLAN']//*[contains(@id, ‘A4')]/../../following-sibling::div[1]/div[1]/span[1]/span[1]”
  “//*[@id='ALARMDATA']//*[contains(@id, ‘AFC2')]/../../preceding-sibling::div[1]/div[1]/span[1]/span[1]”
  “//*[@id='RESEARCH/REVIEW']//widget/section/div[1]/div/div[2]/div[1]/div[3]/div[1]//span[@class='details']”
  “//a[contains(.,'Parameter Data Manual Entry')]”
  “//*[contains(@style,'display: block; top:')]//input[@name='daterangepicker_end']”
  “//*[@id='dropdown-filter-serviceTools']/following-sibling::ul/descendant::a[text()='Notepad']”
  “//*[@id='dropdown-filter-serviceTools']/following-sibling::ul/descendant::a[text()='Trigger Dashboard']”
  “//h3[text()='Internal Debrief']”
  “//h3[contains(text(),'Helium Level')]/following-sibling::div/label/input”
  “//div[div[p[contains(text(),'Status')]]]/preceding-sibling::div/div/span[3]/span”
  “//*[@id='COUPLING']//*[contains(text(),'COUPLE Trend')]/../div/select”
  “//*[@id='ffaHeaderDropdown']//a[contains(text(),'Start Workflow')]”
  
  ......
查看更多精彩内容,请点击下载:

版权声明:本文出自《51测试天地》第五十四期。51Testing软件测试网及相关内容提供者拥有51testing.com内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号