[译] 用 CSS 选择器和自定义属性来升级你的项目

用 CSS 选择器和自定义属性来升级你的项目

这篇文章原文刊登在 TestProject。感谢大家的支持,让 SitePoint 成为可能。css

Selenium WebDriver 的元素选择器是 自动化测试框架 中所说起的核心组件中的一种,同时也是与 web 应用进行交互的关键。在对 自动化元素选择器 的回顾中, 咱们讨论了不少不一样的选择器应用策略,探究其功能,权衡优缺点,最终咱们推荐 最佳的选择器应用策略 —— 带有自定义属性的 CSS 选择器。前端

Selenium 的元素选择器

选择最好的 元素选择器 策略是成功的关键,也减轻了自动化工做的维护压力。所以,作出选择的时候应该从使用难度,多功能性,是否具备在线支持,文档丰富程度以及性能等多方面进行考虑。前期的充分考虑是有回报的,自动化工做会更容易维护。node

就像从技术方面考虑元素选择器同样,也要考虑到团队文化。在自动化工做中采用元素选择器时,在开发者与 QA 之间成熟的合做文化能够解锁更高成就,取得更好的效果。夯实软件开发周期中其它方面的合做基础不只对自动化工做有益,更是对团队有益。python

全部的代码示例都是由 PythonSelenium WebDriver 中的命令编写而成,但也广泛适用于其它编程语言和框架。android

HTML 代码示例:

在每一段的示例中,都是使用如下导航菜单的 HTML 片断代码:ios

<div id="main-menu">
  <div class="menu"><a href="/home">Home</a></div>
  <div class="menu"><a href="/shop">Shop</a>
    <div class="submenu">
      <a href="/shop/gizmo">Gizmo</a>
      <a href="/shop/widget">Widget</a>
      <a href="/shop/sprocket">Sprocket</a>
    </div>
  </div>
</div>
复制代码

糟糕的选择器: 标签名,连接文本,部分连接文本和 name 属性选择器

关于这部份内容不须要花太多时间来说,由于这些选择器的使用场景都颇有限。在整个自动化框架中普遍使用这些选择器不是一个好选择。它们所完成的需求彻底能够经过其它元素选择器策略轻松实现。只有在特定需求中须要去处理特殊案例的时候才使用这几种选择器。即便如此,大多数特殊场景并无特殊到非要使用这几种选择器才能解决。你能够在没有其余选择器选项可用(例如自定义标签或 id)的状况下使用。git

举个栗子:

使用标签名称选择器,会选择到很是多的匹配到标签名称的元素。它的用途很是有限,只能做为在须要选择大量相同类型的元素的惟一状况下的解决方案。下面这个例子会返回示例 HTML 代码中所有 4 个 div 元素。github

driver.find_elements(By.TAG_NAME, "div")
复制代码

也能够像下面的例子这样经过连接来选择。如你所见,这样只能定位到锚点标签并且只能定位这些锚点标签的文本:web

driver.find_elements(By.LINK_TEXT, "Home")
driver.find_elements(By.PARTIAL_LINK_TEXT, "Sprock")
复制代码

最后,也能够经过 name 属性来选择元素,可是在 HTML 代码示例中能够看出,那些标签是没有 name 属性的。这在绝大多数应用中都是一个常见问题,由于给每一个 HTML 属性中添加一个 name 属性不是常规的代码实践。假如主菜单元素像下面同样有一个 name 属性:chrome

<div id="main-menu" name="menu"></div>
复制代码

能够像这样匹配到这个元素:

driver.find_elements(By.NAME, "menu")
复制代码

如你所见,以上这些元素选择策略的使用场景都颇有限。下面的方法都会更好一些,它们更灵活多变。

总结: 标签名,连接文本,部分连接文本和 name 属性选择器

优势 缺点
使用简单 不够灵活
使用场景极其有限
在某些场景甚至可能用不了

还不错的选择器: XPath

XPath 是一种灵活多变的选择器策略。这是我我的很喜欢的。XPath 能够选择页面中的任意元素,不管它有没有 class 和 id (虽然没有 class 和 id 的话很难维护)。该选项很是灵活有用,由于你能够选择 父元素。XPath也有许多内置的功能,可让你自定义元素选择。

可是,多功能性也带来了复杂性。鉴于 XPath 能够作这么多事,相比于其它选择器,它的学习曲线也更陡峭。这一不足是能够被它很是赞的在线文档抵消的。在 W3Schools.com 上找到的 XPath 入门指南 是一个很不错的资源。

还应该指出,使用 XPath 的时候有一件事须要进行权衡。虽然能够经过 XPath 选择父元素并使用一系列内置函数,可是 XPath 在 IE 浏览器的表现不佳。在选择元素选择器策略时,应该考虑这个问题。若是你有选择父元素的须要的话,要考虑它对 IE 上进行的 跨浏览器 测试的影响。本质上,在 IE 中运行自动化测试的耗时更长。若是你的用户群体的 IE 使用率不高的话,考虑到在 IE 上跑测试的时候更少,XPath 依然是一个好选择。若是你的用户基本上都是 IE 重度使用者的话,XPath 就只能做为没有其它更好方式时的备胎选择了。

举个栗子:

若是你有需求要选择父元素,那就必须采用 XPath。下面是作法,依然使用咱们的示例,假设你要定位一个基于锚点元素的主菜单元素的父元素:

driver.find_elements(By.XPATH, "//a[id=menu]/../")
复制代码

这个元素选择器会定位到第一个 id 等于 "menu" 的锚点标签,而后经过 “/../” 定位到它的父元素。最终结果就是你会定位到主菜单元素。

总结: XPath

优势 缺点
能够定位到父元素 IE 上表现欠佳
很是灵活 陡峭的学习曲线
很是多的在线支持

超级棒的元素选择器: ID 和 Class

ID 和 Class 元素选择器在自动化中是两个不一样的选项,会在应用程序中执行不一样的功能。然而做为自动化工做的选择器策略,这两种选择器的区别很小,咱们不必将它们分开考虑。在应用程序中,UI 界面开发者能够操做和给定义了 "id" 和 "class" 属性的元素设置样式。对于自动化工做来讲,咱们使用它们来针对特定元素进行交互。

使用 ID 和 Class 原则器的一大好处是它们受应用程序结构变化的影响最小。假设,你要建立一个链式地依赖于一些元素和 子元素 的 XPath 或 CSS 选择器,若是此时有一个功能须要增长一些新元素从而中断了这个链条,会发生什么?使用 ID 和 Class 元素选择器,您能够定位特定的元素,而不是依赖页面结构。同时也没有过于宽松易变。应该经过给特定元素的位置建立测试用例来自动检测改动。改动不该该毁坏你的整个自动化套件。可是,若是开发者直接对自动化中使用的 ID 或 Class 进行更改的话,仍是会影响到你的测试。

又或者若是 HTML 标签没有自动化程序中可以使用的 ID 和 Class 属性的话,这种策略就没法使用。若是 HTML 标签没有自动化程序中可以使用的 ID 和 Class 属性的话,这种方法就很难使用。

举个栗子:

在示例中,若是咱们想选择到顶级的菜单元素,那应该是这样的:

driver.find_elements(By.ID, "main-menu")
复制代码

若是要选择第一个菜单项,则是这样:

driver.find_elements(By.CLASS_NAME, "menu")
复制代码

总结: ID 和 Class 选择器

优势 缺点
易于维护 开发人员可能会直接修改它们,自动化工做就没法进行了
学习难度低
受页面结构的影响最小

最佳的元素选择器: 具备自定义属性的 CSS 选择器

若是大家的 QA 团队与开发部门合做良好的话,大家颇有可能会选择这种最佳实践方法应用到自动化工做中。使用自定义属性和 CSS 选择器来定位元素对于 QA 团队和整个组织来讲都有不少好处。对于 QA 团队来讲,这可让自动化工程师直接定位到特定元素,无需建立复杂的元素原则器。可是,这须要在应用程序中添加自动化团队所需的属性。为了充分发挥最佳实践的优点,开发部门和 QA 团队应共同实施这一策略。

我想简短地提示一下,CSS 选择器方法并不依赖于自定义属性。CSS 选择器能够像 XPath 同样定位到 HTML 文档流中的任意标签和属性。

如今咱们来看这个方法须要咱们作什么。为了能最好地执行这一策略,大家的自动化团队了解本身在自动化工做中想要定位什么。在与开发人员的合做中,最有多是与前端工程师的合做中,QA 团队须要制定一个自定义属性的应用模式,放到团队所须要链接合做的每个目标中。对于这个例子来讲,咱们把 "tid" 属性附加到了目标元素上。

这里须要强调的一个技术上的注意事项是 CSS 选择器的限制。CSS 选择器是不容许像 XPath 同样选择父元素的。这是为了不页面上 CSS 样式的无限循环。这对网页设计来讲是件好事,可是,当它做为自动化的元素选择器时是一种限制。幸运的是,这种限制能够由开发实现自定义属性来避免。QA 应请求合适的自定义属性,以便无需选择父元素。

若是大家公司的开发部门和 QA 团队不存在合做文化的话,也不用担忧!应该实施这个策略,由于它是能够推进合做的途径。不管这种合做文化是否存在,你也应该先采用这种方式而后看看效果怎么样。你不但会拥有一个易于维护的选择器策略,你还会看到遍布整个公司的协做文化所带来的便利。这种合做关系会在质量保障的多个方面受益,好比减小缺陷,缩短上市时间并提升生产力。

为了更好地实行这个策略并建立合做关系,QA 团队应该从一开始就参与到设计过程当中,与开发部门合做并 review 需求。随着开发部门设计功能,QA 应该建议哪里能够实现自定义属性的位置,以最好地支持自动化工做。经过在设计阶段初期就鼓励这种合做,可以让 QA 团队和开发部门会在合做关系中走得更近,提升开发效率。这也可能会对软件开发周期的其它领域产生溢出效应。在鼓励开发部门与 QA 团队的合做中,他们彼此更将熟悉,一样的,这种关系也会映射到其它领域的合做中。

举个栗子:

在示例 HTML 代码中的锚点元素上使用自定义属性:

<div id="main-menu">
  <div class="menu"><a tid="home-link" href="/home">Home</a></div>
  <div class="menu"><a tid="shop-link" href="/shop">Shop</a>
    <div class="submenu">
      <a tid="gizmo-link" href="/shop/gizmo">Gizmo</a>
      <a tid="widget-link" href="/shop/widget">Widget</a>
      <a tid="sprocket-link" href="/shop/sprocket">Sprocket</a>
    </div>
  </div>
</div>
复制代码

注意,一些元素上有了新属性。咱们建立了一个叫 "tid" 的新属性,与标准的 HTML 属性并没有任何充冲突。有了自定义属性,咱们能够经过一个 CSS 元素选择器去定位它:

driver.find_element(By. CSS_SELECTOR, "[tid=home-link]")
复制代码

假设,你想选择菜单中全部的连接,不管一级菜单仍是二级菜单。你能够经过 CSS 选择器,建立灵活多变的元素选择器组:

driver.find_element(By.CSS_SELECTOR, "#main-menu [tid*='-link']")
复制代码

"*=" 作的是,在全部元素的 "tid" 字段中由通配符搜索 "-link"。把它放到 "#main-menu" ID 选择符的后面,它就只搜索主菜单内的元素了。

若是你想脱离自定义属性来使用这个策略,也依然是正确路线。举例说,你能够经过以下方式定位到 Shop 的子菜单中的连接:

driver.find_element(By. CSS_SELECTOR, "#main-menu .submenu a")
复制代码

这一策略可使得工程师建立易于维护且不受 UI 界面中无关变化影响的自动化工做。选择这一策略是最好的方法。这不只是一个易于维护的自动化解决方案,并且还会鼓励 QA 团队和开发人员之间的合做。

总结:具备自定义属性的 CSS 选择器

优势 缺点
学习难度低 初始阶段就涉及到与开发人员合做
丰富的在线支持
灵活多变
超级棒的兼容性

结论

在自动化框架中实现企业标准级的元素选择器策略有一些很好的选择。应该避免选择像是标签名或连接文本选择器,除非它们是你惟一的选择。XPath,ID 和 Class 选择器则是一个好路线。到目前为止,最好的方法是实现自定义属性并用 CSS 选择器来定位。这也鼓励了开发部门与 QA 团队之间的合做。

这是全部选项的比较表:

1511434384(1).jpg


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索