css选择器 自定义属性
This article was originally published by TestProject. Thank you for supporting the partners who make SitePoint possible.
本文最初由TestProject发布。 感谢您支持使SitePoint成为可能的合作伙伴。
Element selectors for Selenium WebDriver are one of the core components of an automation framework and are the key to interaction with any web application. In this review of automation element selectors, we will discuss the various strategies, explore their capabilities, weigh their pros and cons, and eventually recommend the best selector strategy – custom attributes with CSS selector.
Selenium WebDriver的元素选择器是自动化框架的核心组件之一,并且是与任何Web应用程序进行交互的关键。 在这篇自动化元素选择器的回顾中,我们将讨论各种策略,探讨它们的功能,权衡其优缺点,并最终推荐最佳选择器策略 -CSS选择器的自定义属性。
Choosing the best element selector strategy is critical to the success and ease of maintenance of your automation effort. Therefore, when choosing your selector, you should consider aspects such as ease of use, versatility, online support, documentation and performance. Strong consideration for a proper selector strategy will pay dividends in the future through easy to maintain automation.
选择最佳的元素选择器策略对于自动化工作的成功和易于维护至关重要。 因此,在选择选择器时,应考虑诸如易用性,多功能性,在线支持,文档和性能等方面。 认真考虑适当的选择器策略,将通过易于维护的自动化在未来带来回报。
Just as the technological aspect of element selectors should be considered, so too should the culture of your organization. A mature culture of collaboration between developers and QA will unlock high tiers of success when implementing element selectors in your automation. This benefits the organization beyond just the automation effort by laying the foundation for collaboration in other areas of the Software Development Life Cycle.
正如应考虑元素选择器的技术方面一样,组织的文化也应考虑在内。 在自动化中实现元素选择器时,开发人员和质量保证人员之间成熟的协作文化将释放出巨大的成功。 通过为软件开发生命周期其他领域的协作奠定基础,这不仅使自动化工作受益,还使组织受益。
All code examples will be in Python and Selenium WebDriver commands but should be generally applicable to any programming language and framework.
所有代码示例都将使用Python和Selenium WebDriver命令,但通常应适用于任何编程语言和框架。
I will use the following HTML snippet of a navigation menu for examples in each section:
我将在每个部分的示例中使用以下导航菜单HTML代码段:
<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>I won’t spend too much time on these because they all have limited use. They are generally not a good option for wide adoption across the entire automation framework. They solve specific needs that can be easily covered with other element selector strategies. Only use these if you have a specific need to handle a special case. Even then, most special cases are not special enough to use these. You would use these in a scenario where there is no other selector option available to you (such as custom tags or id).
我不会在这些产品上花费太多时间,因为它们的用途有限。 通常,它们不是在整个自动化框架中广泛采用的好选择。 他们解决了其他元素选择器策略可以轻松满足的特定需求。 仅在有特殊需要时才使用这些。 即使这样,大多数特殊情况仍不足以使用这些特殊情况。 您将在没有其他选择器选项(例如自定义标签或ID)可用的情况下使用它们。
With tag name, you can select large groups of elements that all match the tag name you provided. This has limited use because it would only work as a solution in situations where you need to select large groups of elements of the same type. The example below would return all 4 div elements in the example HTML.
使用标记名称,您可以选择与您提供的标记名称完全匹配的大型元素组。 这种方法的使用受到限制,因为它仅在需要选择相同类型的大型元素组的情况下用作解决方案。 下面的示例将返回示例HTML中的所有4个div元素。
driver.find_elements(By.TAG_NAME, "div")You can select the links with these examples below. As you can see, they can only target anchor tags and only the text of those anchor tags:
您可以在下面的示例中选择链接。 如您所见,它们只能定位到定位标记,并且只能定位这些定位标记的文本:
driver.find_elements(By.LINK_TEXT, "Home") driver.find_elements(By.PARTIAL_LINK_TEXT, "Sprock")Lastly, you can select elements by the name attribute, but as you can see in the example HTML, there are no tags with a name attribute. This would be a common problem in almost any application, since adding a name attribute in every HTML attribute is not a common practice. If the main menu element had a name attribute like this:
最后,您可以通过name属性选择元素,但是如示例HTML所示,没有带有name属性的标签。 在几乎所有应用程序中,这都是一个普遍的问题,因为在每个HTML属性中添加name属性并不是一种常见的做法。 如果主菜单元素具有这样的名称属性:
<div id="main-menu" name="menu"></div>You could select it like this:
您可以这样选择:
driver.find_elements(By.NAME, "menu")As you can see, these element selector strategies have limited use. The approaches that follow are all better approaches because they are much more versatile and capable.
如您所见,这些元素选择器策略用途有限。 遵循的方法都是更好的方法,因为它们具有更多的用途和能力。
XPath is a versatile and capable element selector strategy. This is also my personal preference and favorite. XPath can select any element in the page regardless of whether or not you have classes and IDs to use (although without classes or IDs, it becomes difficult to maintain and sometimes brittle). This option is particularly versatile because you can select parent elements. XPath also has many built-in functions which allow you to customize your element selection.
XPath是一种通用且功能强大的元素选择器策略。 这也是我的个人偏爱和喜爱。 XPath可以选择页面中的任何元素,而不管您是否有要使用的类和ID(尽管没有类或ID,但维护起来很困难,有时甚至很脆弱)。 该选项特别灵活,因为您可以选择父元素 。 XPath还具有许多内置功能,可让您自定义元素选择。
However, with versatility comes complexity. Given the ability to do so much with XPath, you also have a steeper learning curve compared to other element selector strategies. This is offset by great online documentation which is easily found. One great resource is the XPath tutorial found at W3Schools.com
但是,多功能性带来了复杂性。 借助XPath的强大功能,与其他元素选择器策略相比,您的学习曲线也更加陡峭。 易于查找的出色在线文档弥补了这一不足。 很好的资源是W3Schools.com上的XPath教程。
It should also be noted that there is a trade-off when using XPath. While you can select parent elements and have use of very versatile built-in functions, XPath performs poorly in Internet Explorer. You should consider this trade-off when selecting your element selector strategy. If you need to be able to select parent elements, you need to consider the impact it will have on your cross-browser testing in Internet Explorer. Essentially, it will take longer to run your automated tests in Internet Explorer. If your application’s user base does not have high Internet Explorer usage, this would be a good option for you as you might consider running tests in Internet Explorer less often than other browsers. If your user base has significant Internet Explorer usage, you should consider XPath only as a fallback if other better approaches do not work for your organization.
还应注意,使用XPath时需要权衡。 虽然您可以选择父元素并使用非常通用的内置函数,但是XPath在Internet Explorer中的性能很差。 选择元素选择器策略时,应考虑这一折衷。 如果需要能够选择父元素,则需要考虑它将对Internet Explorer中的跨浏览器测试产生的影响。 本质上,在Internet Explorer中运行自动化测试将花费更长的时间。 如果您的应用程序的用户群对Internet Explorer的使用率不高,那么这对您来说将是一个不错的选择,因为您可能会考虑比其他浏览器在Internet Explorer中运行测试的频率更低。 如果您的用户群大量使用Internet Explorer,则在其他更好的方法对您的组织不起作用的情况下,应仅将XPath视为回退。
If you have a requirement to select parent elements, you must select XPath. Here’s how you do that: using our example, let’s say you want to target the parent main-menu element based on one of the anchor elements:
如果需要选择父元素,则必须选择XPath。 操作方法如下:在我们的示例中,假设您要基于锚元素之一定位父主菜单元素:
driver.find_elements(By.XPATH, "//a[id=menu]/../")This element selector will target the first instance of the anchor tag that has the id equal to “menu”, then with “/../”, targets the parent element. The result is that you will have targeted the main-menu element.
该元素选择器将定位ID为“ menu”的锚标签的第一个实例,然后使用“ /../”定位父元素。 结果是您将定位到主菜单元素。
ID and Class element selectors are two different options in automation and perform different functions in an application. However, for considering what element selector strategy to use in your automation, they differ so little, that we don’t need to consider them separately. In the application, the “id” and “class” attributes of elements, when defined, allow the UI developer to manipulate and style the application. For automation, we use it to target a specific element for interaction in automation.
ID和Class元素选择器是自动化中的两个不同选项,它们在应用程序中执行不同的功能。 但是,对于考虑在自动化中使用哪种元素选择器策略,它们之间的差异很小,因此我们无需单独考虑它们。 在应用程序中,元素的“ id”和“ class”属性在定义时允许UI开发人员操作和设置应用程序样式。 对于自动化,我们使用它来针对特定元素进行自动化交互。
A large benefit to using IDs and Class element selectors is that they are least impacted by structural changes in the application. Hypothetically speaking, if you were to create an XPath or CSS selector that relied on a chain of few elements and some child elements, what happens when a feature request interrupts that chain by adding new elements? When using ID and Class element selectors, you can target specific elements instead of relying on page structure. You retain the robustness of your automation without being too lenient on change. Change should be detected through automation by creating test cases that focus on the location of specific elements. Change should not break your entire automation suite. However, if the developer makes a change directly to an ID or class utilized in automation, that will impact your tests.
使用ID和Class元素选择器的最大好处是,它们受应用程序结构更改的影响最小。 假设地说,如果要创建一个XPath或CSS选择器,它依赖于几个元素和一些子元素的链,当功能请求通过添加新元素来中断该链时会发生什么? 使用ID和Class元素选择器时,可以定位特定元素,而不必依赖页面结构。 您可以保持自动化的稳定性,而不必对变更过于宽容。 应该通过创建侧重于特定元素位置的测试用例来通过自动化来检测更改。 更改不会破坏您的整个自动化套件。 但是,如果开发人员直接更改自动化中使用的ID或类,则会影响您的测试。
This element selector strategy would not be usable if the application under test does not implement IDs and classes as a part of development best practices. If HTML tags do not have IDs and classes you can use in your automation, this approach becomes hard to use.
如果被测应用程序未实现ID和类作为开发最佳实践的一部分,则此元素选择器策略将不可用。 如果HTML标记没有可在自动化中使用的ID和类,则此方法将变得难以使用。
In our example, if we were to select the top level menu element, that would look like this:
在我们的示例中,如果我们选择顶级菜单元素,则将如下所示:
driver.find_elements(By.ID, "main-menu")If we were to select the first menu item, that would look like this:
如果我们选择第一个菜单项,则如下所示:
driver.find_elements(By.CLASS_NAME, "menu")If your QA organization has a good collaborative relationship with development, chances are you will be able to use this best practice approach for your automation. Using custom attributes and CSS Selectors to target elements has multiple benefits for both the QA team and the organization. For the QA team, this allows automation engineers to target specific elements they need without creating complicated element selectors. However, this requires the ability to add custom attributes that the automation team can use in the application. To take advantage of this best practice approach, your development and QA teams should work in cooperation to implement this strategy.
如果您的质量保证组织与开发部门之间拥有良好的协作关系,那么您很有可能可以使用这种最佳实践方法来实现自动化。 使用自定义属性和CSS选择器定位元素对于质量检查团队和组织都有很多好处。 对于质量检查团队,这使自动化工程师可以针对他们需要的特定元素,而无需创建复杂的元素选择器。 但是,这需要能够添加自动化团队可以在应用程序中使用的自定义属性。 为了利用这种最佳实践方法,您的开发和质量检查团队应该合作实施该策略。
I’d like to take a minute to note that the CSS Selector approach is not dependent on custom attributes. CSS Selectors can target any tag and attribute within an HTML document just like XPath.
我想花一点时间注意CSS Selector方法不依赖于自定义属性。 CSS选择器可以像XPath一样定位HTML文档中的任何标签和属性。
Now let’s look at what this approach entails. To best execute this, your automation team should understand what they want to target in their automation. Working with the developers, most likely the front end engineers, they would then work out a pattern for a custom attribute to place into each target the automation team needs to hook into. For this example, we attach a “tid” attribute to the target elements.
现在让我们看一下这种方法的含义。 为了最好地执行此操作,您的自动化团队应该了解他们想要在自动化中定位的目标。 然后,与开发人员(很可能是前端工程师)合作,他们将为自定义属性制定一种模式,以将其放入自动化团队需要挂钩的每个目标中。 对于此示例,我们将“ tid”属性附加到目标元素。
One technical note to highlight here is a limitation in CSS Selectors. They are intentionally not allowed to select parent elements like XPath can. This is done to avoid infinite loops in CSS styling on web pages. While this is a good thing for web design, it is a limitation for its use as an automation element selector strategy. Fortunately, this limitation can be avoided with custom attributes implemented by development. QA should request the appropriate custom attributes so that there is no need to select a parent element.
这里要强调的一个技术说明是CSS选择器的局限性。 故意禁止他们选择XPath可以的父元素。 这样做是为了避免网页CSS样式中的无限循环。 尽管这对于Web设计是一件好事,但它作为自动化元素选择器策略的使用受到了限制。 幸运的是,使用开发实现的自定义属性可以避免这种限制。 质量检查人员应请求适当的自定义属性,以便无需选择父元素。
If the collaboration between your development and QA team doesn’t exist yet in your organization, don’t worry! You should implement this strategy because it can be the mechanism that drives that collaboration. Regardless of whether that culture exists or not, you should take on this approach and watch what comes of it. Not only will you have an easy to maintain element selector strategy, but you will see benefits from the collaboration spill-over into other areas of your organization. The collaborative relationship this will build will benefit you across many aspects of quality assurance such as reduced defects, reduced time to market, and increased productivity.
如果您的组织中尚不存在开发人员和质量检查团队之间的协作,请不要担心! 您应该实施此策略,因为它可以成为推动协作的机制。 不管这种文化是否存在,您都应该采用这种方法并观察它的来龙去脉。 您不仅将有一个易于维护的元素选择器策略,而且还将看到协作所带来的好处,这些好处将扩展到您组织的其他领域。 这将建立的协作关系将在质量保证的许多方面使您受益,例如减少缺陷,缩短上市时间和提高生产率。
To best implement this element selector strategy and to create that collaboration, your QA team should be involved with the design process from the beginning. Working with development, they should review the requirements. As development designs the feature, QA should suggest where custom attributes can be implemented to best support the automation effort. By encouraging this collaboration at the beginning of the design phase, you will move the QA and development teams closer together in terms of collaboration and improve efficiency in the development process. This will likely have a beneficial spill-over effect into other areas of the Software Development Life Cycle. Encouraging collaboration here will familiarize development and QA with each other so that collaboration in other areas is likely to occur as well.
为了最好地实施此元素选择器策略并创建协作,您的质量保证团队应从一开始就参与设计过程。 在进行开发时,他们应该检查需求。 当开发人员设计功能时,质量保证人员应建议可以在何处实施自定义属性,以最好地支持自动化工作。 通过在设计阶段开始时鼓励这种协作,您将使QA和开发团队在协作方面更加紧密,并提高了开发过程的效率。 这可能会对软件开发生命周期的其他领域产生有益的溢出效应。 在这里鼓励合作将使开发和质量保证彼此熟悉,因此其他领域的合作也可能会发生。
Implementing custom attributes on the anchor tags in our example HTML would result in something like this:
在示例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>Notice the new attribute in some of the elements. We created a new attribute that does not conflict with any standard HTML attribute called “tid”. With this custom attribute, we can use a CSS selector to target it:
注意某些元素中的新属性。 我们创建了一个新属性,该属性与任何称为“ tid”的标准HTML属性都不冲突。 有了这个自定义属性,我们可以使用CSS选择器来定位它:
driver.find_element(By. CSS_SELECTOR, "[tid=home-link]")Let’s say you wanted to select all of the links in the menu, regardless of whether it’s a top level menu item or a submenu. With CSS Selectors, you can create highly versatile element selectors:
假设您想选择菜单中的所有链接,而不管它是顶层菜单项还是子菜单。 使用CSS选择器,您可以创建通用性强的元素选择器:
driver.find_element(By.CSS_SELECTOR, "#main-menu [tid*='-link']")What the “*=” does is do a wildcard search for the value “-link” within the tid field of any element. Placing this behind the #main-menu ID specifier, it focuses the search for elements to within the main menu.
“ * =”的作用是对任何元素的tid字段中的值“ -link”进行通配符搜索。 将其放置在#main-menu ID说明符的后面,它将搜索元素集中到主菜单中。
If you want to select this strategy without the use of custom attributes, you are still on the right track. For example, you can target the links in the Shop submenu using the following approach:
如果您想在不使用自定义属性的情况下选择此策略,那么您仍然处在正确的轨道上。 例如,您可以使用以下方法来定位“商店”子菜单中的链接:
driver.find_element(By. CSS_SELECTOR, "#main-menu .submenu a")This strategy will allow automation engineers the ability to create solid automation that is easy to maintain and is not broken by irrelevant changes in the UI. Selecting this strategy is the best possible approach. It will not only be an easily maintainable solution for automation but will encourage collaboration between your QA team and your developers.
该策略将使自动化工程师能够创建易于维护且不会因UI无关更改而被破坏的可靠自动化。 选择此策略是最好的方法。 它不仅将是易于维护的自动化解决方案,而且将鼓励您的质量保证团队与开发人员之间的协作。
There are some great options for implementing an enterprise standard element selector strategy in your automation framework. Options like the tag name or link text should be avoided unless it’s your only option. XPath, ID, and Class selectors are a good route. By far, the best approach is to implement custom attributes and target them with CSS Selectors. This also encourages collaboration between the development and QA team.
在自动化框架中有一些很棒的选项可用于实施企业标准元素选择器策略。 除非是唯一的选择,否则应避免使用诸如标签名或链接文本之类的选项。 XPath,ID和Class选择器是一个不错的选择。 到目前为止,最好的方法是实现自定义属性,并使用CSS选择器作为目标。 这也鼓励开发和质量检查团队之间的合作。
Here are your options compared side-by-side:
以下是您并排比较的选项:
✓ – Yes / – Partial ✗ – No Tag Name, Link Text (etc.) XPath ID & Class Custom Attributes with CSS Selectors Easy to Use✓✓✓✓Online Support✓✓✓✓Versatile✗✓✗/Performance✓✗✓✓Easy to Maintain✗✓✓✓Encourages Collaboration✗✗✓✓ ✓–是 / –部分 ✗–否 标签名称, 链接文本(等) XPath 编号和类别 使用CSS选择器的自定义属性 易于使用 ✓ ✓ ✓ ✓ 在线支持 ✓ ✓ ✓ ✓ 多才多艺 ✗ ✓ ✗ / 性能 ✓ ✗ ✓ ✓ 易于维护 ✗ ✓ ✓ ✓ 鼓励合作 ✗ ✗ ✓ ✓翻译自: https://www.sitepoint.com/upgrade-project-css-selector-custom-attributes/
css选择器 自定义属性