0


Python Selenium 测试教程(一)

原文:Python Testing with Selenium

协议:CC BY-NC-SA 4.0

一、Selenium 简介

在 Selenium 出现之前,测试 web 应用的功能是手工完成的,这需要花费很多时间。测试往往依赖于不同的场景。每个场景都被认为是一个测试用例,用来在实现之前制定 web 应用的行为。这些测试用例被部署在各种浏览器上,以确认源代码中的任何问题。

它需要一个专门的测试团队来检查所有的测试用例。准确性和时间是 web 开发中的主要约束,这导致了自动化测试用例可以在不同的 web 应用中使用,而无需更改源代码。Selenium 是为了自动化测试用例而开发的。

这本书的第一章提供了 Selenium 及其核心架构设计的完整概述。子主题解释了 Selenium 的使用,并将其与该领域中的其他测试工具进行了比较。在本章的后面,将解释 Python 与 Selenium 的集成。让我们从 Selenium 工具的简要历史和描述以及使用它的原因开始。

Selenium 是什么?

Selenium 于 2004 年出现在 ThoughtWorks,用于测试 Jason Huggins 开发的名为 Time and Expenses 的 web 应用。开发该工具是为了在各种浏览器中测试应用的前端行为。这个工具很受欢迎并且是开源的。自动化测试需求的增长导致了几年来 Selenium 的几个版本的开发,这将在下面讨论。

Selenium 工具和版本

ThoughtWorks 发布了 Selenium 的四个主要版本来测试 web 应用。图 1-1 显示了每个版本及其发布年份。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-1

Selenium 套件

组织可以使用这些 Selenium 工具中的任何一个(或多个);选择取决于测试环境的需求。ThoughtWorks 开发的第一个工具是 2004 年的 Selenium Core。它允许测试人员编写他们自己的代码/脚本来自动化前端交互,如键盘或鼠标活动。这些活动类似于用户与应用的交互。

在 web 应用安全性中,有一个策略授予测试脚本访问来自相同来源的网页中的数据的权限;这种策略被称为相同主机策略。同主机策略只允许一个测试用例访问同一个域中的页面。比如一个测试脚本可以访问 www.apress.com 内的多个页面,比如 www.apress.com/in/pythonwww.apress.com/in/about ,因为同宿策略;但是,该策略不允许访问来自不同站点的页面,如 https://google.comhttps://wikipedia.org

由于相同主机策略,当使用外部脚本时,对代码元素的访问被拒绝或阻止。为了避免这种复杂性,Huggins 和 Paul Hammant 开发了一个服务器组件,使您能够用测试脚本测试 web 应用,让浏览器认为两者来自同一来源。这种核心 Selenium 最终被称为驱动 Selenium 或 Selenium b。

Selenium 遥控(遥控)

Selenium RC (remote control)是由 Dan Fabulich 和 Nelson Sproul 在 2005 年部署的,它支持使用 HTTP 代理的独立服务器。这解决了 Selenium Core 在相同主机策略下面临的问题。Selenium RC 分为两部分:Selenium 远程服务器和远程客户端。服务器和客户端接收和发送 HTTP 请求所花费的时间导致测试用例的执行速度变慢;因此,Selenium RC 成为最少使用的工具。

Selenium IDE

2006 年,Shinya Kasatani 为测试人员开发了一个完全集成的开发环境(IDE)。它是以 Mozilla Firefox 和 Google Chrome 网络浏览器插件的形式出现的。Selenium IDE 在真实环境中进行了功能测试。这个 IDE 的特性包括记录/重放和调试/编辑测试,这就是 Selenium Recorder。记录脚本存储在一个名为 Selenium 的测试脚本中。测试脚本是用 Java、Ruby、JavaScript 和 PHP 等语言编写的。IDE 还为针对 web 应用执行的测试用例提供了数据检索选项。Selenium IDE 目前由 Kantu 和 Katalon 积极维护。

Selenium 栅

很难在市场上出现的新技术设备上测试 web 应用。为了解决这个问题,2008 年,ThoughtWorks 的 Philippe Hanrigou 开发了一种网格架构,允许您通过浏览器在任意数量的远程设备上测试应用,这就是后来的 Selenium Grid。它减少了在任意数量的远程设备上测试脚本的时间,因为它是并行完成的。test 命令通过浏览器测试远程设备。在远程设备上执行测试脚本需要两个组件:集线器/服务器和节点/远程设备。

集线器/服务器从允许访问的 web 驱动程序客户端获取请求,并将其路由到远程驱动程序。这些驱动程序在远程设备上注册。节点/远程设备具有本地操作系统和浏览器。web 驱动程序是执行测试的浏览器的一部分。在定义脚本时,您需要命名一个远程设备、平台、浏览器等等,以定位一个特定的节点,然后为该节点执行测试脚本。

Selenium WebDriver

Selenium WebDriver 是一个广泛使用的工具。Selenium RC 的进步导致了 Selenium WebDriver 的开发。WebDriver 中的命令通过客户端 API 接受,并被发送到不同的浏览器,如 Mozilla Firefox、Apple Safari 等。几乎所有的浏览器都支持 Selenium WebDriver。每个浏览器都有一个与之相关的特定驱动程序,如表 1-1 所列。

表 1-1

Web 浏览器及其各自的 Selenium 驱动程序
|

网络浏览器

|

驱动程序名称

|
| — | — |
| Mozilla Firefox | Firefox(即壁虎) |
| 谷歌浏览器 | 铬 |
| 苹果浏览器 | 旅行队 |
| 歌剧 | 歌剧 |
| 浏览器 | 微软公司出品的 web 浏览器 |
| 微软边缘 | 边缘 |

维护表中列出的每个驱动程序,以支持其各自浏览器的自动化。另一个浏览器驱动程序 HTMLUnitDriver 使用一个无头浏览器(HtmlUnit)来模拟浏览器。

Selenium WebDriver 允许您直接启动 web 浏览器,并通过执行命令来管理它。为了避免安全冲突和问题,WebDriver 使用本机操作系统功能,而不是基于浏览器的 JavaScript 命令。WebDriver 的 Selenium WebDriver 版本专注于接口。之后的版本是 Selenium 2.0 和 Selenium 3.0。

Selenium 2.0

2007 年,ThoughtWorks 的 Simon Stewart 开发了 Selenium 2.0,它可以在几乎所有的浏览器上实现自动化。这个版本调用更少,允许测试人员/开发人员创建他们自己的领域特定语言(DSL)。用 Ruby 实现的 Watir web 驱动程序是 DSL 最好的例子之一。

Selenium 3.0

开发人员西蒙·斯图尔特(Simon Stewart)和大卫·伯恩斯(David Burns)制定了一个草案来标准化 Selenium,该草案被完全接受,并在 2019 年成为 W3C 标准协议,当时它被称为 Selenium 3.0。

这就完成了 Selenium 及其多年演变的概述;现在,在深入测试用例之前,让我们考虑一下 Selenium 架构,这将在本书接下来的章节中介绍。

Selenium WebDriver 架构

现在您已经了解了 Selenium 的各种工具和版本,让我们来看看一个帮助 web 应用自动化测试脚本的工具。为了自动化一个测试脚本,在工具和浏览器之间有一个只有它的架构才能理解的交互。

Selenium WebDriver 是 Selenium 套件中的一个工具,可以为任何 web 应用自动化测试用例。web 驱动工具和应用之间的交互经历了不同的阶段。这些阶段形成了一个架构,如图 1-2 所示。Selenium WebDriver 的架构由三个主要组件组成:Selenium 客户端库、浏览器驱动程序和 web 浏览器。组件之间的通信是通过 JSON 协议完成的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-2

Selenium WebDriver 架构

客户端库

客户机库是 Selenium 支持的语言包。Selenium 支持的核心语言有 Python、Java、JavaScript、Ruby、C# ( https://selenium.dev/downloads/ )。像 Perl、PHP、GO、DART、R、Haskell 等语言都是由第三方维护开发的( https://selenium.dev/thirdparty/ )。Selenium 不正式支持这些第三方语言绑定。

JSON 有线协议

JSON 是 JavaScript Object Notation 的首字母缩写,它是一种轻量级协议,在客户机和服务器之间交换数据或信息,反之亦然。JSON 是一种易于理解的文本格式,这使得 ThoughtWorks 开发人员能够使用 JSON wire 协议在客户端库和 web 浏览器驱动程序之间进行通信。服务器不关心客户端使用的语言;它只能从协议中读取以 JSON 格式接收的数据。JSON wire 协议将任何数据或信息在发送到服务器之前都转换成 JSON 格式。这是一个 REST API。

Note

REST(表述性状态转移)定义了一套开发 API(应用编程接口)的准则。规则之一是当链接到一个 URL 时从源获得服务器响应。

Web 驱动程序

每个浏览器都有一个相关联的网络驱动程序(更多信息请参考表 1-1 )。这些 web 驱动程序负责执行从客户端库接收的命令。这些命令的执行是在 web 浏览器中完成的,它通过 HTTP 进行通信。

网络浏览器

执行从 web 驱动程序的 HTTP 响应中收到的命令。像客户端库一样,可以使用核心和第三方浏览器。Selenium 支持的浏览器有 Firefox、Internet Explorer、Safari、Opera、Chrome 和 Edge。这些浏览器可以在任何操作系统上运行,比如 Windows、macOS 或 Linux。有为这些 web 浏览器开发的第三方 web 驱动程序,但不推荐使用。

为什么是 Selenium?

研究了 Selenium WebDriver 架构之后,让我们进一步加深您对 Selenium 的理解。

由于市场上测试工具的可用性,出现了一个问题:为什么使用 Selenium 进行测试?这个问题有几个答案,但是使用 Selenium 的主要原因是它是开源的(即可以免费使用)。接下来讨论使用 Selenium 作为测试工具的好处。

开放源码

Selenium 是开源的,可以免费使用。有一个庞大的开发人员/测试人员社区在持续维护和支持它。您可以为任何测试环境修改、集成或扩展 Selenium,因为代码是开源的。

平台

Selenium WebDriver 是跨平台的,这意味着它可以灵活地在任何操作系统中自动化测试用例,比如 Windows、macOS、Unix 和 Linux。这些在一个操作系统中编写的测试用例可以在任何其他操作系统中使用。

语言支持

Selenium 拥有大型社区的另一个原因是它支持多种编程语言和脚本,如 Python、Java、Ruby、Perl、PHP、JavaScript、Groovy、GO、DART 等等。Selenium WebDriver 语言绑定/客户端库支持这一点。

浏览器

与平台灵活性一样,Selenium WebDriver 支持几乎所有的浏览器。支持 Mozilla Firefox、Google Chrome、Safari、Opera、Internet Explorer、Edge 它们是全球使用最广泛的。

再用

一旦编写完成,测试脚本可以根据需要跨任何浏览器或操作系统使用。对多次使用一个测试脚本没有限制。

易于实施

Selenium WebDriver 的实现依赖于开发人员/测试人员或组织所使用的环境和脚本。这种多样性源于大量潜在的操作系统和浏览器组合。您可以开发定制的 web 驱动程序或框架,以便在特定的测试环境中实现。

灵活的

在测试脚本中进行重构或重组,可以让您减少代码重复和其他复杂性。Selenium 在测试脚本中为开发人员/测试人员提供了这种灵活性。

硬件资源

与其他测试工具(如 UFT、CompleteTest、Katalon Studio 等)不同,Selenium 需要的硬件资源更少。

模拟

Selenium 的模拟创建了鼠标和键盘的实时行为。这有助于使用鼠标测试高级事件,如拖动、放下、单击、按住、滚动等,以及在键盘上进行类似的按键事件。

到目前为止讨论的各种原因应该满足使用 Selenium 作为测试工具的理由,但是与其他可用的工具进行比较可以确保 Selenium 在自动化测试方面是最好的。这将在下面讨论。

其他测试工具

既然您已经知道了 Selenium 提供的好处,现在让我们将 Selenium 与测试领域中其他可用的测试工具进行比较。这个比较显示了在 Python 中使用 Selenium 的确切原因。对测试工具的各种特性进行了比较。还有其他四种主要的测试工具可用。表 1-2 展示了这些测试工具。

表 1-2

将 Selenium 与其他测试工具进行比较
| |

Selenium

|

加泰罗尼亚工作室

|

UFT(统一功能测试)

|

测试完成

|

沃特沃特 Walter

|
| — | — | — | — | — | — |
| 发布年份 | Two thousand and four | Two thousand and fifteen | One thousand nine hundred and ninety-eight | One thousand nine hundred and ninety-nine | Two thousand and eight |
| 测试平台 | 十字架 | 十字架 | Windows 操作系统 | Windows 操作系统 | 十字架 |
| 测试应用 | 开发 | 网络/移动应用、API/网络服务 | Windows/web/移动应用,API/web 服务 | Windows/web/移动应用,API/web 服务 | 网络/移动应用 |
| 语言支持 | Python,Java,C#,Perl,JavaScript,Ruby,PHP | Java/Groovy | 脚本语言 | Python、JavaScript、VBScript、Jscript、Delphi、C++、C# | 红宝石 |
| 安装过程 | 易于过渡(取决于 Selenium 工具) | 容易的 | 容易的 | 容易的 | 先进的 |
| 编程技巧 | 中级到高级(用于编写所需的测试用例) | 先进的 | 先进的 | 先进的 | 先进的 |
| 成本 | 自由的 | 自由的 | 许可维护费 | 许可维护费 | 自由的 |
| 许可证类型 | 开源(Apache2.0) | 免费软件 | 所有人 | 所有人 | 开源(麻省理工学院许可) |
| 产品支持 | 开源社区 | 社区/业务支持 | 敬业的工作人员/社区 | 敬业的工作人员/社区 | 开源社区 |

现在您可以看到 Selenium 是测试 web 应用的最合适的自动化工具,让我们看看为什么 Python 是与 Selenium 集成的最佳语言。

将 Python 与 Selenium 集成

现在,Selenium WebDriver

已经讨论过了,您可能想知道使用哪种语言来自动化测试脚本或用例。Selenium WebDriver 支持多种语言。下面列出了 Python 是最适合测试的语言的原因。

  • Python 是在英语范围内开发的,所以代码语法很容易阅读。
  • Python 脚本不是机器级别的代码,这使得编码很容易。
  • Python 提供跨平台支持,这导致了一个庞大的追随者社区。
  • 在 Selenium WebDriver 上安装 Python 比任何其他语言都容易。
  • Python 支持 web 和移动应用的开发。Python 开发人员可以很容易地迁移到 Selenium WebDriver 来测试他们的应用,因为 Selenium 在 Python 中受支持。
  • Selenium 提供了直接连接到浏览器的 Python API。由于 Python 不太冗长,Selenium 命令在连接到任何受支持的浏览器时都很容易编写和执行。
  • Python 编程语言是一个脚本;因此,不需要编译器将代码从一种形式转换成另一种形式。
  • Python 有巨大的库支持,因为它背后有大量的社区,他们定期维护和更新它。Selenium WebDriver 可以根据组织或个人的需要通过自动化来扩展,以构建更高级的测试用例。
  • Python 库也支持不同的语言绑定。这有助于自动化用其他语言开发的应用的测试用例。

清单 1-1 到 1-5 为 Selenium WebDriver 支持的语言提供了一个简单的程序。该程序打开浏览器,访问指定的 URL,并在其中搜索查询。该程序首先导入必要的 Selenium WebDriver 库。WebDriver 然后打开 Mozilla Firefox 浏览器,指定 www。阿普瑞斯。com 作为访问的网址。接下来,它在 press 站点中定位搜索栏元素。找到元素后,这本书的书名Python Testing with Selenium,作为查询输入搜索栏并提交。提交的查询提供了一个新的网页,其中包含与该查询相关联的书籍。

清单 1-1 到 1-5 展示了与 Java、C#、Ruby 和 PHP 等其他编程语言相比,Python 使用 Selenium web driver 实现测试用例是多么容易。

<?php

require_once('vendor/autoload.php');
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;

$web_driver = RemoteWebDriver::create("https://api_key:[email protected]/wd/hub",
        array("platform"=>"WINDOWS","browserName"=>"chrome","version"=>"latest","name"=>"First Test"),120000);
$web_driver->get("http://apress.com");

$element = $web_driver->findElement(WebDriverBy::name("query"));if($element){
$element->sendKeys("Python with Selenium");
$element->submit();}print$web_driver->getTitle();
$web_driver->quit();
?>

Listing 1-5PHP Code
//Library Import
require "selenium-webdriver"// Open Firefox
browser= Selenium::WebDriver.for:firefox

// Visit Apress Site
browser.navigate.to "http://www.apress.com"// Finding Element of search bar
search=browser.find_element(:name,'query')// Search Book name
search.send_keys"Python Testing with Selenium"// Submit book name
search.submit

//Closing browser
browser.close

Listing 1-4Ruby Code
//Importing Libraries in C#
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;classApress{
staticvoid Main(){// Opening Browser
    WebDriver browser = newFirefoxDriver();// Visit Apress Site
    browser.Navigate().GoToUrl("http://www.apress.com");// Finding Element of search bar by name
    WebElement search = driver.FindElement(By.Name("query"));// Search Book name
    search.SendKeys("Python Testing with Selenium");// Submit book name
    search.Submit();// Submit book name
    browser.Close();}}

Listing 1-3C# Code
//Importing Libraries in JAVA
importorg.openqa.selenium.By;
importorg.openqa.selenium.WebDriver;
importorg.openqa.selenium.WebElement;
importorg.openqa.selenium.firefox.FirefoxDriver;

public classSearch{

public static void main(String[] args){//Opening Firefox Browser
        WebDriver browser = new FirefoxDriver();//Opening Apress Website
        browser.get("http://www.apress.com");//Finding Element of search bar
        WebElement search =driver.findElement(By.name("query"));//Searching book name as query
        search.sendKeys("Python Testing with Selenium");//Submitting the query
        search.submit();//Closing browser
        browser.close();}}

Listing 1-2Java Code
#Importing selenium libraries in pythonfrom selenium import webdriver

#Opening web Firefox browser using webdriver
driver=webdriver.Firefox()#Adding URL to open in browser
driver.get("http://www.apress.com")#Finding Element of search bar
search=driver.find_element_by_name("query")#Searching book name as string/query in search bar
search.send_keys("Python Testing with Selenium")#Submit string to search bar
search.submit()# Close Firefox browser
driver.quit()

Listing 1-1Python Code

摘要

本章概述了 Selenium WebDriver,包括对其各种版本的介绍。重点是 Selenium 的架构设计,它提供了自动化测试用例所必需的完整交互过程。讨论了 Selenium 的重要性,包括它的多种好处以及它与其他主要测试工具的区别。在本章的最后,使用 Python 和其他语言在简单的测试案例场景中展示了 Python 与 Selenium 集成的重要性。我们进一步研究如何在不同的环境中进行集成。Python 的设置和配置将在下一章阐述。

二、入门指南

在前一章中,讨论了 Selenium 及其架构设计的完整概述,包括将 Python 与 Selenium 集成的意义。现在让我们深入了解集成。

本章涵盖了使用 Selenium 和 Python 编写自动化测试用例的基本构件。它解释了所需工具的配置和安装,包括 Selenium 库。它还介绍了与各种浏览器相关的 Selenium 驱动程序的配置。

在写测试用例之前,你需要知道初始化测试用例的浏览器命令,这在本章的例子中有所说明。

Note

Selenium 中的 Python 脚本被描述为一个测试用例

本章的前半部分致力于 Python 编程语言、Selenium 包和可用驱动程序的安装。本章的后半部分介绍了使用安装的 web 驱动程序运行测试用例所必需的基本浏览器命令。让我们从基本的 Python 安装开始。

安装 Python

首先,你需要安装 Python。如果您不熟悉 Python,请按照以下步骤在 Windows 中安装它。

  1. 打开浏览器,进入 https://python.org/downloads/windows/
  2. 下载标题为 Python Releases for Windows 下的任何版本。(选择高于 3.6.0 的 Python 版本;撰写本文时的最新发布版本是 3.8.5。)
  3. 选择 Windows 版本(64 位的 Windows x86-64 可执行安装程序或 32 位的 Windows x86 可执行安装程序)。
  4. 运行 Python 安装程序,并向其中添加 Python 路径。注意 Python 预装在 Mac 和 Linux 上。

现在您可以为 Python 安装 Selenium 库了,这将在下面解释。

安装 Selenium

一旦 Python 安装在您的系统上,您就可以利用 pip 下载 Selenium 包。使用 pip 安装 Selenium 的命令是

pip install selenium

通过用另一个包名替换

selenium

,同样的语法可以用于其他的包安装,这将在本书的另一章中讨论。本书使用的 Selenium 版本是 3.141.0。如果已经安装了 Selenium 库的较低版本,或者需要升级当前版本,请使用下面的命令。

     pip install --upgrade selenium

接下来解释下一个过程,Selenium 支持的驱动程序安装。

安装驱动程序

需要驱动程序才能与指定的浏览器交互。每个浏览器都有一个特定的 Selenium WebDriver 与之关联,因此您需要安装所提供的任何一个驱动程序;例如,geckodriver 是一个 Selenium WebDriver,它只能在 Mozilla Firefox 上运行。表 2-1 列出了每个驱动程序及其相关的安装源。

表 2-1

Web 驱动程序和安装源
|

Web 驱动程序

|

来源

|
| — | — |
| Mozilla Firefox | https://github.com/mozilla/geckodriver/releases |
| 谷歌浏览器 | https://sites.google.com/a/chromium.org/chromedriver/downloads |
| 微软边缘 | https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ |
| 苹果浏览器 | https://webkit.org/blog/6900/webdriver-support-in-safari-10/ |

安装完您选择的驱动程序后,您需要学习与浏览器相关的基本命令。这些浏览器命令是运行书中解释的任何测试用例所必需的。接下来让我们看看各种浏览器命令。

浏览器命令

现在让我们看看如何在不同的浏览器中运行一个测试用例。这是运行测试用例的第一步。稍后,将讨论每个浏览器命令。

要在 Selenium 中初始化测试用例,您需要知道基本的浏览器命令。打开指定的 web 浏览器对于任何测试用例的发生都是强制性的。下面讨论可用的命令。

打开 Web 浏览器

Selenium 支持多种 web 浏览器,每种浏览器都有自己的驱动程序。应该使用相关驱动程序的可执行路径来打开任何 web 浏览器。打开驱动程序的语法是

driver = webdriver.Browser_name(executable_path="driver_path")

Mozilla Firefox

在打开 Firefox 之前,需要导入必要的 Selenium 库。应该创建 WebDriver 实例来打开此浏览器。

#Import Selenium Libraryfrom selenium import webdriver

#Open Mozilla Firefox
driver = webdriver.Firefox(executable_path=r'C:\Driver\path\ \geckodriver.exe')

谷歌 Chrome

在 Chrome 中执行任何测试用例之前,需要安装 Chrome 驱动程序。您可以使用以下命令在此浏览器中进行测试。

from selenium import webdriver

#Open Google Chrome
driver = webdriver.Chrome(executable_path=r'D:\chromedriver.exe')

微软边缘

要在微软 Edge 浏览器中测试一个案例,需要安装 Edge 驱动,然后使用 Selenium WebDriver 执行。

from selenium import webdriver

#Open Microsoft Edge
driver = webdriver.Edge(executable_path=r'D:\msedgedriver.exe')

微软公司出品的 web 浏览器

在该浏览器中测试案例需要 Internet Explorer 可执行文件的路径。

#Import Selenium Libraryfrom selenium import webdriver

#Open Internet Explorer
driver = webdriver.Ie(executable_path=r'D:\IEdriverserver.exe')

Note

Mozilla Firefox 是本书中最常用的网络驱动。

关闭浏览器

close()

函数使用 Selenium 驱动程序关闭当前打开的窗口。它不影响打开的其他窗口。执行过程保持活动状态。

from selenium import webdriver
driver = webdriver.Firefox()

driver.get('https://apress.com')print("Browser Window opened")#Close function
driver.close()print("Browser Window closed")

退出浏览器

quit()

功能关闭所有打开的窗口。它还终止驱动程序的执行过程。

from selenium import webdriver
driver = webdriver.Firefox()

driver.get('https://google.com')print("Browser opened")#Quit function
driver.quit()print("Terminates process")

打开网页

测试在网页打开时进行,web 元素被包装在其中。网页可以在线或离线打开(即,有或没有任何互联网连接)。为了打开一个 web 页面,Selenium 使用了

get()

方法,该方法初始化将在指定浏览器中加载的页面。有两种打开网页的方法,下面将讨论这两种方法。

在线打开页面

HTTP 或 HTTPS 协议用于打开在线 web 应用或页面。

get()

方法完成网页的加载,然后将控制权转移到下一行代码。

from selenium import webdriver
driver = webdriver.Firefox()#Open web page online
driver.get('https://apress.com')print("Page opened Online")
脱机打开网页

离线打开页面用于在本地测试网页或 web 应用。要执行测试,您需要将文件本地存储在计算机上。这适用于不需要互联网连接的页面。您需要提供文件位置而不是 URL,以便在浏览器中打开它。

from selenium import webdriver
driver = webdriver.Firefox()#Open web page offline
driver.get('file:///C:/File/Path/file_name.html')print("Page opened Offline ")

表 2-2 描述了

get()

方法打开网页所支持的协议。

表 2-2

get()方法支持的协议
|

协议

|

描述

|
| — | — |
| 文件 | 用于存储在本地计算机上的网页 |
| 超文本传送协议 | 测试服务器上承载的网页 |
| 安全超文本传输协议 | 在服务器上进行测试时,有两种不同的协议与域相关联,即 HTTP 或 HTTPS。 |

当协议不匹配时,Selenium 抛出一个异常。

设置浏览器大小

大多数 web 应用或网页都是使用响应式框架开发的。响应网页根据浏览器大小进行调整。为了测试不同浏览器大小的页面,Selenium 提供了下面讨论的命令。

达到最大值

Selenium 中的

maximize

功能最大化当前网页浏览器。测试人员用它来测试网页的响应性。当它没有以最大化状态打开时,由浏览器使用。

from selenium import webdriver

driver = webdriver.Firefox(executable_path=r'C:\Users\ADMIN\Desktop\geckodriver.exe')#Open apress webpage
driver.get('https://apress.com')#Maximise Window
driver.maximize_window()print("Browser is maximised")

当浏览器已经处于最大化状态时,该功能对浏览器没有任何影响。

全屏
fullscreen

功能将浏览器设置为全屏模式。标题、URL、地址栏、选项卡等在全屏显示的网页上是不可见的。

from selenium import webdriver

driver = webdriver.Firefox()#Open apress webpage
driver.get('https://apress.com')#FullScreen
driver.fullscreen_window()print("Browser is Fullscreen")
设置尺寸

这个函数通过设置高度和宽度来调整浏览器窗口的大小。调整浏览器大小以测试 web 应用/页面的响应性。

from selenium import webdriver

driver = webdriver.Firefox()#Open apress webpage
driver.get('https://apress.com')#Set Window Size
driver.set_window_size(500,400)print("Sets Browser Size")

设置浏览器位置

Python Selenium 中的

set

方法沿着 x 和 y 轴设置浏览器位置。x 和 y 的位置从屏幕右上角的(0,0)开始。

from selenium import webdriver

driver = webdriver.Firefox(executable_path=r'C:\Users\ADMIN\Desktop\geckodriver.exe')#Open apress webpage
driver.get('https://apress.com')#Set Window Position
driver.set_window_position(x=500,y=400)print("Sets Browser Position")

使用坐标设置大小

此方法用位置和尺寸设置浏览器。位置与 x 和 y 坐标有关,而尺寸与高度和宽度有关。

from selenium import webdriver

driver = webdriver.Firefox()#Open apress webpage
driver.get('https://apress.com')#Set Window Size with co-ordinates
driver.set_window_rect(x=30, y=30, width=450, height=500)print("Sets Browser Size with co-ordinates")

获取浏览器位置

在一些测试用例中,浏览器位置是执行基于它的动作所必需的。

get

方法返回浏览器窗口相对于 Python 字典中 x 和 y 位置的位置。

from selenium import webdriver

driver = webdriver.Firefox()#Open apress webpage
driver.get('https://apress.com')#Get Window Position
window_pos= driver.get_window_position()print(window_pos)

获取窗口大小

使用此函数时,浏览器窗口的高度和宽度将在 Python 字典中返回。

from selenium import webdriver

driver = webdriver.Firefox()#Open apress webpage
driver.get('https://apress.com')#Get Window Sizeprint(driver.get_window_size())

导航命令

导航命令与浏览器特征相关,浏览器特征使得测试者能够通过使用后退和前进命令或刷新命令来导航浏览历史。Python Selenium 支持这些命令。

背部
back()

功能用于在同一个浏览器标签中导航到以前访问过的页面。

from selenium import webdriver

driver = webdriver.Firefox()#Open apress webpage
driver.get('https://apress.com')#Open Google page
driver.get('https://google.com')#Go back to previous 'apress' page
driver.back()print("Moved to first page")
向前

此功能有助于点击网络浏览器的

forward

按钮,最终进入下一页(如果可用)。

from selenium import webdriver

driver = webdriver.Firefox(executable_path=r'C:\Users\ADMIN\Desktop\geckodriver.exe')#Open apress webpage
driver.get('https://apress.com')#Open Google page
driver.get('https://google.com')#Go back to previous 'apress' page
driver.back()print("Moved to first page")#Go to current page
driver.forward()print("Moved to second page")
恢复精神
refresh()

功能在网络浏览器中重新加载当前页面。

from selenium import webdriver
driver = webdriver.Firefox()#Open apress webpage
driver.get('https://apress.com')print("Page will be Refreshed")#Page refresh command
driver.refresh()print("Page is Refreshed")

接下来讨论运行测试用例的传统方式。

运行 Python 测试用例

现在让我们运行 Python 文件(即测试用例)。运行测试用例的过程只需要几个简单的步骤。

下面解释了如何在 Windows 中执行 Python 测试用例文件。

  1. 单击位于屏幕左下角的 Windows 按钮。
  2. 输入cmd关键字,这是命令提示符的快捷方式。点击它。
  3. 使用以下命令将路径更改为测试用例所在的文件位置。
  4. 使用以下命令运行测试用例。
cd dsktop/selenium
python file_name.py
.py

是 Python Selenium 的测试用例扩展。

摘要

在本章中,您学习了安装 Python 及其 Selenium 库的基本过程。本章还解释了在 Selenium 环境中安装和实现一些 web 驱动程序。您了解了每个 web 驱动程序的初始化以及一些相关的浏览器命令。随着您逐步阅读下一章,这些基本的浏览器命令会变得更加具体。在本章的最后,你经历了一个运行测试用例的过程化方法。

下一章解释了使用相同 web 浏览器命令的鼠标和键盘操作。

三、鼠标和键盘操作

前一章介绍了用 Selenium 安装和配置 Python 来自动化测试用例。还回顾了在 WebDriver 中运行测试用例所必需的基本 web 浏览器命令。本章将指导您完成用户使用鼠标和键盘在 web 应用中进行的所有操作。

在 web 应用中,web 元素被绑定到某些需要执行的动作或事件,以执行一个完整的测试用例。当用 Selenium 操作命令测试这些操作或事件时,会发现与用户界面相关的错误。

在 web 应用中,用户/客户端使用各种鼠标和键盘操作。Selenium 提供了 ActionChain,这是一个强大的库函数,用于测试页面上任何 UI 元素的用户行为。在 UI 元素上执行动作功能之前,您需要定位它(参见第四章)。

动作链

ActionChains 在一个测试用例中自动化了低级别的鼠标和键盘交互。交互通过设备(即鼠标或键盘)进行分类,并根据与之相关的类似事件进一步分类。

perform()

是一个重要的功能,使鼠标和键盘的所有动作得以执行。只有在使用

perform()

功能时,与鼠标和键盘相关的所有 ActionChains 功能才起作用;如果没有使用,ActionChain 函数将不会在网页上执行任何操作。

当用于 web 元素时,多个操作在队列中对齐。这些动作在调用

perform()

函数后执行。在使用

perform()

功能之前需要进行操作(稍后将演示鼠标和键盘操作的示例)。现在让我们检查一些与鼠标相关的动作。

老鼠

鼠标可以执行点击、拖动、移动等操作和动作。这些操作是通过 web 应用中的 web 元素执行的。例如,按钮的选择,如默认提交按钮,是通过点击鼠标完成的(参见第六章),或者在执行此操作后显示或定位一个 web 元素。

可以通过单击或多次单击鼠标左键或右键来完成单击。Python 中的 Selenium 提供了测试与鼠标相关的动作的方法,这将在下面描述。

点击

click(web_element)

是通过点击鼠标左键选择网页元素的功能。传递的参数用于一个需要选择或单击的 web 元素。

当没有参数(即 web 元素)被传递时,鼠标左键被点击到它在 web 应用中的当前位置。

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

driver.get("http://www.apress.com")# Go to button
web_element=driver.find_element_by_link_text("Apress Access")#Clicking on the button to be selected
web_element.click()

点击并按住

click_and_hold(web_element)

是一种方法,首先将鼠标指针移动到特定的 web 元素,然后使用鼠标左键单击相同的元素。单击后,元素不会被释放,因此会保持不动。

在下面的示例中,单击并按住元素的中间。

from selenium import webdriver
driver=webdriver.Firefox()# Direct to url
driver.get("http://www.apress.com")# Locate 'Apress Access' web element button
button=driver.find_element_by_link_text("Apress Access")# Execute click-and-hold action on the element
webdriver.ActionChains(driver).click_and_hold(button).perform()

上下文点击

context_click(web_element)

是一个将鼠标指针移动到特定 web 元素的函数,然后在该元素上启动上下文点击。鼠标右键点击在 ActionChains 中被称为上下文点击

这里有一个例子。

driver.get("http://www.apress.com")# Go to button
button=driver.find_element_by_link_text("Apress Access")# Perform context-click
webdriver.ActionChains(driver).context_click(button).perform()

如果在上下文函数中没有定义 web 元素,那么在当前位置单击鼠标按钮。

双击

double_click(web_element)

是一种方法,鼠标指针指向定位的 web 元素,然后双击鼠标左键(双击)。

这里有一个例子。

driver.get("http://www.apress.com")# Go to button
button=driver.find_element_by_link_text("Apress Access")# Double click on button
webdriver.ActionChains(driver).double_click(on_element=button).perform()

当没有指定元素时,它单击当前位置。

移动到一个元素

move_to_element(web_element)

函数将鼠标移动到 web 元素上。它主要集中在下拉菜单上,在那里你可以滚动或点击鼠标。

这里有一个例子。

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

driver= webdriver.Firefox(executable_path=r'C:\Users\ADMIN\Desktop\geckodriver.exe')

driver.get("http://www.apress.com")

main_menu=driver.find_element_by_link_text("CATEGORIES")
ActionChains(driver)\
        .move_to_element(main_menu)\
        .perform()# Wait for sub menu to be displayed
WebDriverWait(driver,3).until(EC.visibility_of_element_located((By.LINK_TEXT,"Python")))

sub_menu=driver.find_element_by_link_text("Python")
sub_menu.click()

(除了 ActionChains(将在后续章节中讨论)之外,还有其他一些与异常和等待相关的库导入。)程序将鼠标指针移动到主菜单中的 Categories 链接,并等待三秒钟跳转到 Python 子菜单。

移动偏移量

鼠标从当前位置移动到指定的 x 和 y 偏移量。函数中的 x 和 y 偏移值是一个整数,可以是正数也可以是负数。下面是语法。

move_by_offset(xoffset, yoffset)
driver.get("http://www.apress.com")#Offset positions of x and y
x =268
y =66#Move element with offset position defined
webdriver.ActionChains(driver).move_by_offset(x,y).perform()

当指定的坐标超出网页窗口时,则鼠标移出窗口。偏移的默认坐标是(0,0)。

下面的语法反映了用指定的坐标移动鼠标。这里,鼠标相对于元素位置移动。早期的方法是将鼠标的移动作为一帧覆盖整个屏幕。

move_to_element_with_offset(to_element, xoffset, yoffset)

偏移值从任何指定 web 元素的左上角开始。该值是一个整数,可以是正数,也可以是负数。负的

xoffset

值表示指定 web 元素的左侧。类似地,

yoffset

中的负值表示 web 元素向上的一侧。下面是这个函数的一个例子。

driver.get("https://www.apress.com/")# get  element
element = driver.find_element_by_link_text("CATEGORIES")# create action chain object
action = ActionChains(driver)# perform the operation
action.move_to_element_with_offset(element,200,50).click().perform()

当 web 元素静态放置在网页上时,可以使用偏移位置,但不能用于相对位置。

拖放

drag_and_drop()

拖动源元素到指定或目标位置。源元素是需要被拖到目标位置的 web 元素。

以下是拖放元素的 HTML 代码。

<html><head><style type="text/css">#drag,#drop {float:left;padding:15px;margin:15px;-moz-user-select:none;}#drag{ background-color:#A9A9A9; height:50px; width:50px; border-radius:50%;    }#drop{ background-color:#fd8166; height:100px; width:100px; border-radius:50%;  }</style><script type="text/javascript">
function dragStart(ev){

ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));

ev.dataTransfer.effectAllowed='move';
ev.dataTransfer.setDragImage(ev.target,0,0);return true;}
function dragEnter(ev){
event.preventDefault();return true;}
function dragOver(ev){return false;}
function dragDrop(ev){
var src=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(src));
ev.stopPropagation();return false;}</script></head><body><h1>Drag and Drop</h1><center><div id="drop" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)">Drop here</div><div id="drag" draggable="true" ondragstart="return dragStart(event)"><p>Drag</p></div></center></body></html>

为这两个元素定义了两个圆,其中一个元素可以拖动较小的圆放到较大的圆上。这是一个拖放元素的简单例子。在网页上,拖放功能通常用于将图像滑块或文件移动到上传的特定区域。

下面是 Selenium 代码来拖拽图 3-1 所示的圆。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-1

拖放

from selenium import webdriver
driver=webdriver.Chrome()# Navigate to page stored as local file
driver.get("drag_and_drop.html")# Locate 'drag' element as source
element1 =driver.find_element_by_id("drag")# Locate 'drop' element as target
element2  =driver.find_element_by_id("drop")# Perform drag and drop action from
webdriver.ActionChains(driver).drag_and_drop(element1,element2).perform()

拖放通过

使用

drag_and_drop_by
(source, x_offset, y_offset)

,按住鼠标左键,直到它将 web 元素分别移动到定义的 x 和 y 偏移值,然后松开按钮。web 元素是给定语法中的源元素。

这里有一个例子。

driver.get("drag_and_drop.html")#Locate circle1 element
circle1 =driver.find_element_by_id("drag")#Locate circle2 element
circle2  =driver.find_element_by_id("drop")#Getting offset values
x_off=circle2.location.get("x")
y_off=circle2.location.get("y")#PerformdragAndDropBy to circle2 element
webdriver.ActionChains(driver).drag_and_drop_by_offset(circle1, x_off, y_off).perform()

Note

由于 Firefox 和 Selenium 之间的兼容性问题,普通 JavaScript 使用的拖放功能可能不起作用。

释放;排放;发布

release()

功能释放被点击的鼠标左键。它对于与拖放相关的 web 元素最为有效。如果没有 web 元素被传递,那么鼠标按钮在网页上的当前位置被释放。

这里有一个例子。

driver.get("drag_and_drop.html")#Locate circle1 element
circle1 =driver.find_element_by_id("drag")#Locate circle2 element
circle2  =driver.find_element_by_id("drop")#Release action after performing necessary actions
ActionChains(driver).click_and_hold(circle1).move_to_element(circle2).perform().release().perform()

既然我们已经回顾了 Selenium 中 ActionChains 的所有鼠标操作,现在让我们来看看键盘操作。

键盘操作

键盘操作也是与 web 应用交互所必需的。四个主要动作与键盘相关联。接下来将讨论这些操作。

向下按键

key_down(value, web_element)

功能通过按键来工作。它主要与修饰键一起使用,如 Shift、Control、Alt 等。

键起

key_up(value, web_element)

功能释放按下的修改键。它通常在 key down 方法之后使用。

发送密钥

send_keys_to_element( send_keys)

方法将键盘上的按键发送到当前选中的 web 元素。它可用于单键或多键。

大多数时候,键盘动作是一起使用的。下面是从网页中选择和复制文本的键盘操作的简单示例。

#Import necessary librariesfrom selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

driver=webdriver.Chrome()

driver.get('https://en.wikipedia.org/wiki/Apress')

ActionChains(driver)\
        .key_down(Keys.CONTROL)\
        .send_keys("a")\
        .key_up(Keys.CONTROL)\
        .key_down(Keys.CONTROL)\
        .send_keys("c")\
        .key_up(Keys.CONTROL)\
        .perform()

在代码中,您会看到使用 Selenium 中可用的键盘操作选择并复制了 web 页面的所有内容。

向元素发送密钥

send_keys_to_element
(web_element, send_keys)

中,键被发送到给定函数中的 web 元素,这与只发送键的 send keys 函数不同,因为它没有提到任何元素。

鼠标和键盘动作可以组合起来用于网页上的一个或多个 web 元素。

中止

pause(secs)

中,动作被延迟(暂停)一段指定的时间(秒)。它在执行操作之前显示一个 web 元素。

重置

reset_actions()

函数清除或删除所有存储的与 web 元素相关的动作。动作可以存储在本地或远程端。

摘要

这一章主要讲述了用户在与网页交互时使用的鼠标和键盘操作。本章从 Selenium 支持的所有鼠标操作开始。然后,演示各种动作及其对应的示例。稍后,您学习了用户可以使用的四个主要键盘功能。

在应用这些操作之前,您需要找到该元素。定位 web 元素的任务由 Selenium 中的 web 定位器完成,这将在下一章讨论。

四、网页元素

在前一章中,您已经了解了鼠标和键盘的基本操作。现在您需要找到一个 web 元素来执行这些操作。本章解释了如何定位 web 元素。有几种类型的 web 元素可用于构建 web 应用。要测试 web 应用,首先需要跟踪其中的 web 元素。元素可以在网页上的任何地方。这些 web 元素可以通过 Selenium WebDriver 提供的定位器来定位或跟踪。

定位器在 web 应用中查找 web 元素;因此,整个章节都致力于 web 元素和定位器。测试用例中还演示了具有内置函数的定位器。在深入研究 web 定位器及其类型之前,让我们从了解什么是 web 元素开始。

元素/Web 元素

元素通常被定义为开始和结束 HTML 标记之间的任何东西。网页或应用由许多不同的元素组成。这些在 web 应用中多次使用的元素被称为 web 元素

Note

术语元素web 元素可以互换使用。

为了避免服务于相同目的的多个 web 元素之间的混淆,使用唯一的属性来区分它们。定义的属性有一个相应的名称,该名称应该是唯一的,作为 web 元素的唯一属性。该属性有助于定位器。

Note

Web 元素可以位于页面上的任何位置。

现在您对 web 元素有了基本的了解。要识别网页上可用的 web 元素,您需要了解定位器。由于每个 web 元素都是不同的,因此有不同的 web 定位器,这将在下面讨论。

网络定位器

网页上至少需要有一个 web 元素,这是使用 web 定位器的一个基本条件。在自动化任何测试之前,您需要在 web 应用或网页中的许多其他元素中识别或找出特定的 web 元素。定位器标识特定的 web 元素。

locator 是 Selenium WebDriver 的一个简单函数或方法。定位器使用 Selenium 支持的不同属性来识别 web 元素。有八个唯一的定位器(函数)来标识 web 元素,下面将对此进行描述。

这些函数提供了跟踪或识别 web 元素以保护脚本的灵活性。让我们看看定位 web 元素的不同方式。

定位元件

网页是使用链接、字段、文本、图像等元素构建的。这些元素在 HTML 中是标签的形式,有时在 HTML 中不是。为了定位这些元素,Selenium 使用定位器。

本章介绍的八种定位器。解释了语法,如何、何时以及在哪里使用这些定位器,使您能够在以后的测试用例中使用它们。

让我们分别看一下这些 web 定位器。

ID 定位器

这种方法或函数是使用最广泛的定位器之一。id 是 HTML 网页中唯一的属性,不太可能受变化的影响。这是在 HTML 页面上定位元素的最简单也是最受欢迎的方法之一。

根据 W3C,每个元素必须有唯一的 ID;然而,浏览器允许这个规则的一个例外。这个异常允许不同的元素具有相同的 ID 名称或者没有 ID,这就是为什么 Selenium 有八个定位器。下面是语法。

var_name = find_element_by_id ('id_attribute')

考虑下面的 HTML 页面源代码。

<html><body><form id="EmployeeForm"><input name="employee_name"type="text"/><input name="email"type="email"/><input name="next"type="submit" value="Login"/></form></body></html>

在 HTML 源代码中,form 标记是唯一具有 ID 属性的元素。表单标签的 ID 属性被命名为

EmployeeForm

。使用语法,下面的代码有助于跟踪/查找具有 ID 属性的元素。

Employee_form = driver.find_element_by_id ('EmployeeForm')

通过使用这种方法,如果 ID 属性已知,就可以很容易地定位元素。如果多个元素具有相同的 ID 属性名,则返回第一个匹配的 ID。如果不匹配,则调用异常。这种异常称为 NoSuchElementException。

名称定位器

一个元素可能有多个关联的属性。name 属性是一个广泛使用的属性,但它可能是也可能不是唯一定义的。name 属性通常是表单上的输入元素(但也用于文本字段和按钮中)。在表单上执行提交操作时,name 属性将所有相应的值传递给服务器。

var_name = find_element_by_name ('name_attribute')

下面的 HTML 源代码显示了如何定位具有 name 属性的元素。

<html><body><form id="EmployeeForm"><input name="employee_name"type="text"/><!--1st element--><input name="email"type="email"/><!--2nd element--><input name="next"type="submit" value="Login"/><!--3rd element--><input name="next"type="button" value="Clear"/><!--4th element--></form></body></html>

有两个带有名称属性的输入标签。第一个和第二个输入标签(元素)以

employee_name

作为名称属性,电子邮件元素很容易定位,如下所示。

#Locating first element
employee = driver.find_element_by_name('employee_name')#Locating second element
email = driver.find_element_by_name('email')

在每种情况下,名称定位器都与 HTML 源页面上的第一个元素匹配。如果页面上没有匹配的元素,则调用 NoSuchElementException。

在多个元素具有相同名称作为属性的情况下,定位器选择 HTML 页面上具有确切指定名称的第一个元素。

next= driver.find_element_by_name('next')

在前面的方法中,返回登录按钮,因为它出现在清除按钮之前。要从一个页面返回多个元素,请参考“定位元素”一节。

XPath 定位器

XML 语言中使用 XPath 来定位通过元素和属性导航的节点。路径由与特定节点相关联的表达式组成。HTML 也支持使用 XHTML 实现 XML。在没有 ID 和名称的情况下,很难定位元素。在这些情况下,XPaths 定位器通过链接来识别元素。它是仅次于 ID 和名称的第三大常用定位器。有几种方法可以定位链接,因为它们是树状结构。

XPath 的一般语法是

  • //:定义当前目录/标签(单斜线表示绝对路径)
  • tag_name:定义指定路径的标签名称
  • @:指定要选择的属性
  • attribute_name:指定属性的名称;节点属性的名称
  • :定义指定属性的值
xpath =//tag_name[@attribute_name='value']

为了更好地理解 Xpath,您需要了解 XML 文档。XML 文档是树形结构,具有各种相关的属性和标签。下面以 XML 文档的形式显示了雇员的树形结构。

<employee><department ="Testing"><fname>John </fname><lname>Wick</lname><title>Senior Tester</title><salary>$10000</salary></department><department ="Development"><fname>Harry</fname><lname>Potter</lname><title>Junior Developer</title><salary>$5000</salary></department></employee>

节点形成树状结构。这些节点有一个根节点,DOM 结构就是从这个根节点开始的。其他节点被视为叶节点或子节点。

Note

根节点也称为父节点起始节点初始节点

XML 文档结构如图 4-1 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-1

XML 文档结构的文档对象模型

XML 文档只包含一个根 web 元素,它是一个雇员。employee web 元素有两个节点作为部门:测试开发。这些部门也被称为根元素的属性。

每个部门包含另外四个属性:fname、lname、title 和 salary。这四个属性与它们各自的值相关联。测试部门雇员的值如下:fname 是 John,lname 是 Wick,title 是 Senior Tester,salary 是$10000。同样,对于开发部门,值为哈利、波特、初级开发人员和 5000 美元。

以下 XML 页面源由各种标记和属性组成。您还需要了解一些术语,这将在接下来的章节中介绍。

节点

在网页中,树状结构表示 DOM。节点从结构的起点到终点相互连接。初始节点被称为根节点。它有时被称为初始节点

在 HTML 中,

<html>

标签是根节点或节点开始的初始节点。

双亲

嵌入在开始和结束标记之间的 web 元素有一个关联的父元素。除了根节点之外,任何元素都至少有一个父元素。head 和 body 标签有一个 HTML 标签作为父标签,这是一个根元素。

孩子们

父元素可以有一个或多个子元素。head、body 和 div 标签有与其相关联的子标签。有时,父标签没有子标签,例如 title 标签。

同科

属于同一父元素的 web 元素被称为兄弟元素。例如,div 标签中的所有标签都是兄弟标签。

原子值

没有父元素或子元素的 web 元素被称为原子值。最好的例子是没有子节点的根节点。

XPath 方法

XPath 轴通过使用与 XML 中相同的结构树机制来帮助导航或定位 web 元素。web 元素的动态特性使得定位 XPath 变得困难,因此 axes 方法解决了这个问题。

XPath 轴有 13 种不同的方法来定位复杂或动态的 web 元素。

儿童

它定位与网页/应用上的当前或所选 web 元素相关联的所有可用子元素。

父母

它定位当前 web 元素的父元素。如果当前元素没有任何父元素,则根节点被视为其父元素。根元素是所有可用元素的父元素。

自轴

它只检测一个 web 元素(即自身)。

祖先

它定位从当前元素的父元素开始到其所有可用祖先(即,父元素、祖父元素、曾祖父元素等)的所有 web 元素。).它包含根元素,除非它是根元素。

祖先或自我

在这种情况下,将定位所选 web 元素的所有可用祖先,包括当前元素。

后裔

它定位所有子 web 元素。后代包括当前元素的子元素和孙元素。

后代还是自己

它包括当前元素及其所有子元素。如果没有子元素,那么只返回当前元素。

跟随

它定位当前元素之后的所有 web 元素。它不包括当前元素。

跟随兄弟姐妹

它将所有 web 元素定位在当前元素之后的同一级别。例如,任何选择框或单选按钮元素。

在前的

它定位出现在页面上当前元素之前的所有 web 元素。

前面的兄弟姐妹

它定位出现在同一级别的选定元素之前的所有同级元素。

属性

使用属性定位 web 元素后,将检查指定元素的该属性。如果匹配,则返回该元素;否则,它返回一个空值。

命名空间

它定位与名称空间相关联的所有 web 元素。这是最少使用的 XPath 轴之一。

Note

没有子元素(即

()

)的 web 元素被称为叶节点

节点示例

下面的 HTML 定义了一个结构及其关系。这种关系如图 4-2 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-2

HTML 标签之间的关系

<html><!-- Root node--><head><!-- Parent --><!--Child of head tag--><title></title></head><body><!-- Parent --><!--<div>Child of body
And Parent of header, section, aside, footer --><div><!—Child one--><header></header><!—Child two--><section></section><!—Child three--><aside></aside><!—Child four--><footer></footer><!-- The four tags header, section,
aside and footer are siblings to each other --></div></body></html><!-- End Node -->

根节点或开始节点是初始的 HTML 标签。HTML 标签有两个子元素:head 和 body。头只有一个子元素标题。head 分别是 HTML 标签的子标签和标题的父标签。head 和 body 标签是兄弟。

类似地,body 有一个子元素:div。div 标签有四个子标签。div 是 body 标记的子元素,是四个子元素的父元素:header、section、side 和 footer。这四个元素是兄弟元素,没有任何自己的子元素。div 标记没有同级。

HTML 是所有元素的祖先。同样,头部和身体只是它们的子元素的祖先。title 和 div 元素是 HTML 元素的子元素。这个头没有孙子。身体有四个孙辈。子代(ren)和孙代(ren)分别是父代和祖父代的后代。同样,父元素是子元素(ren)和孙元素(ren)的祖先。

标头是其他三个兄弟的前一个兄弟。页脚是前三个同级的下一个同级。同样,头部和身体分别是前面和后面的兄弟。

Note

XPath 依赖于浏览器,因为每个浏览器的行为都不同。

XPath 定位器类型

XPath 中有两种定位器可以用来在 Selenium 中定位 web 元素。接下来将讨论它们。

绝对路径

绝对路径是一种直接定位 web 元素的方法。它是最简单的 XPath,存在于 DOM 结构中。如果在此路径中进行了任何更改,web 元素将无法定位元素。绝对路径是 web 元素可用的路径。

绝对路径从根节点(即初始节点)开始。节点之间的连接由单个正斜杠(

/

)表示。该路径按照从顶层节点开始的分层顺序排列。

考虑下面的 HTML 代码,它显示了绝对路径是如何导出的。

<html><title></title><head></head><body><form id="EmployeeLogin"><input name="fname"type="text" value="First Name"/><!--Input1--><input name="lname"type="text" value="Last Name"/><!--Input2--><input name="email"type="text" value="Email"/><!--Input3--><inputtype="text" name="location" value="Location"><!--Input4--><input name="password"type="password"/><!--Input5--><input name="continue"type="submit"
            value="Employee Login"/><!--Input6--></form></body></html>

绝对路径定位 HTML 代码中位置字段的输入。输入字段位于数字 4 的位置,所以它的绝对路径是

form_element= driver.find_element_by_xpath
                                ("/html/body/form/input[4]")

Note

在 Selenium 中,索引从 1 而不是 0 开始。

在前面的绝对路径中,路径从根节点(即 HTML 节点)开始,到 input[4]节点结束,input[4]节点是要定位的 web 元素。这里所需的 web 元素是 location 字段,它位于所描述路径的结束节点。

Note

绝对路径从根节点开始,到需要定位的节点结束。

相对路径

在相对路径中,web 元素位于 DOM 结构中,这使得它不太容易被更改。相对路径比绝对路径更有助于定位 web 元素。

XPath 可以从 web 页面中的任何地方开始(即 DOM 结构),在 web 元素需要定位的节点处结束。节点之间用双斜线(

//

)分隔,而不是单斜线。

Note

在相对路径中,当前目录作为参考。

相对路径使用比绝对路径更短的路径来定位 web 元素。如前面的 HTML 代码所述,要定位位置字段,其相对路径如下。

form_element= driver.find_element_by_xpath
                                        ("//form//input[4]")

这里,节点从表单元素开始,到第四个输入字段结束。末端是要定位的元素。

Note

斜线很容易区分绝对路径和相对路径。在 Xpath 中,单斜线表示绝对路径,双斜线表示相对路径。

带有逻辑运算符的 XPath

带有逻辑运算符的 XPath 表达式允许您在网页上检查或定位多个 web 元素。逻辑运算符也称为布尔运算符,因为它可能会也可能不会返回指定的元素。web 元素使用逻辑运算符至少需要两个 XPath 表达式,因此一个逻辑运算符可以定位一个或多个 web 元素。web 元素的返回取决于指定的条件。

指定条件的结果为真或假。当结果为真时,它返回一个 web 元素,否则不返回任何元素。下面描述两个主要的逻辑运算符。

当两个 XPath 指定的属性匹配或在给定网页上可用(存在)时,AND 逻辑运算符返回或定位 web 元素;否则,它不返回任何 web 元素。如果 web 元素或其属性不可用,则会发生 NoElementFoundException。

and

是该运算符使用的关键字。

form_element=driver.find_element_by_xpath("//input[@name='fname'and @type='text']")

在该示例中,当输入 web 元素匹配与其关联的名称和类型属性时,将返回该元素。表 4-1 显示了元素的位置。

表 4-1

Web 元素结果的条件
|

A

|

B

|

结果

|
| — | — | — |
| 错误的 | 错误的 | 未找到元素 |
| 真实的 | 错误的 | 未找到元素 |
| 错误的 | 真实的 | 未找到元素 |
| 真实的 | 真实的 | 定位两个元素(A&B) |

类似地,当使用 AND 逻辑运算符通过指定两个相关属性来返回多个 web 元素时,它将返回一个 False 值。当属性属于不同的元素时,这可以被验证并实现。下面是另一个展示 XPath 返回多个 web 元素的例子。

form_elements=driver.find_elements_by_xpath("//input[@name='fname'and @name='lname']")

两个 web 元素通过它们的名称属性来定位。

运筹学

在这种逻辑运算符类型中,当两个指定属性或 web 元素中的任何一个在网页上可用时,它仅返回真布尔值的 web 元素。当两个条件都为假时,它不返回任何元素。关键词是

or

。下面是一个简单的例子,其中使用 or 逻辑运算符检查输入表单的属性。

form_elements=driver.find_elements_by_xpath("//input[@name='fname']or[@name='newpassword']")

此示例检查与输入表单相关联的两个属性——名称和类型。如果任何属性属于所述的任何输入表单,那么它返回相应的 web 元素。在这种情况下,将返回第一个输入框(Input1 ),但是没有类型为

newpassword

name 属性的输入表单。

表 4-2 显示了网络元素的逻辑值。

表 4-2

或带有 Web 元素结果的条件
|

A

|

B

|

结果

|
| — | — | — |
| 错误的 | 错误的 | 未找到元素 |
| 真实的 | 错误的 | 定位元素 a |
| 错误的 | 真实的 | 定位元素 b |
| 真实的 | 真实的 | 定位两个元素(A&B) |

类似地,输入表单的三个不同属性也提到了

or

逻辑操作符。比较的 web 元素的属性是名称和类型。所有属性都属于给定输入表单中的每个不同的 web 元素;因此,它返回所有相关的输入表单。

form_elements=driver.find_elements_by_xpath("//input[@name='fname']or[@name='lname']or[@type='email']")

or

逻辑代码片段中,从一到三的前三个输入表单作为结果被检索。逻辑操作符的使用在 Selenium 中不受限制,因此可以用于多个 web 元素。

Note

两个逻辑运算符都区分大小写(即

and

or

)。

XPath 函数的类型

在一个 web 应用/页面中有许多 web 元素,这会使定位具有相同属性的元素成为问题;例如,具有相同属性的几个按钮,如名称或 id。为了定位这些 web 元素,Selenium 提供了 Xpath 函数。优选地,这些功能与动态变化的 web 元素一起使用。接下来讨论一些常用的 XPath 函数。

包含( )
contains()

是一种用于动态改变与 HTML 页面中的 web 元素相关联的属性中的值的方法。当您知道 XPath 中实现的部分属性值或部分链接文本时,可以使用它。

contains()

函数在网页上搜索给定的文本,如果匹配就返回 web 元素。它通常用于登录页面,其中登录 ID 会动态变化。

contains()

函数的语法是

//xpath[contains(@attribute,'attribute value')]

下面是

contains()

在完整和部分文本中的例子。

//with complete text
element1 =driver.find_elements_by_xpath("//input[contains(@id, 'fname']")//with Partial Link
element2 =driver.find_elements_by_xpath("//input[contains(@name, 'pass']")

使用我们之前的表单 HTML 示例,这个代码片段中的 web 元素搜索文本并为

element1

返回 input1,为

element2

返回 input5。你需要明白,

element2

被提供了部分文本(

pass

’),它匹配表单输入的 name 属性(

password

’)。因此,部分文本允许您定位动态 web 元素。

文本( )

在 web 元素缺少属性的情况下,

text()

函数允许您通过识别某些文本来定位元素。具有该文本的 web 元素被定位。

//xpath[text()='login-in']

下面的 html 代码片段使用

text()

函数来跟踪 web 元素。

<button type="button"> Submit <button/>

element3 =driver.find_elements_by_xpath("//button[text() = 'Submit']")

按钮标记没有属性;它只有相关的文本。

text()

函数用于定位该元素。

element3

检索带有与其相关的

'submit'

文本的按钮。

以( )开头

该函数非常类似于 contains 函数;唯一的区别是,它从检查 XPath 之后提供的初始字符串开始。这个函数非常适合那些在页面重新加载后值会发生变化的 web 元素。匹配初始字符串或文本以定位 web 元素。

下面是一个通用语法示例。

//xpath[starts-with(@attribute,'attribute value')]

element4 =driver.find_elements_by_xpath("//form[starts-with(@id, 'Employee']")
element4

的字符串

id

是初始值,与页面上可用的表单 ID 相匹配。

CSS 选择器

CSS 选择器和 XPath 是相似的,因为它们都可以检测网页上复杂的 web 元素。CSS 选择器比 XPath 更容易实现,因为 CSS 与 DOM 无关,并且在定位 web 元素时更加灵活。当一个网页集成了很多 CSS 时,使用 CSS 选择器来定位网页元素是很容易的。它也很健壮。

Note

CSS 是级联样式表的首字母缩写。这是使 HTML 页面具有吸引力的主要因素。

CSS 选择器是由一个元素选择器和它对应的值组合而成的。这个对应的值定位或标识页面中的 web 元素。该值可以是 ID、标签、属性值等形式。

当 CSS 选择器用于定位 web 元素时,当与指定的属性匹配时,将返回网页中的第一个元素。如果没有元素符合指定的条件,则会引发异常。CSS 选择器的一般语法是

find_element_by_css_selector()

以下方法展示了一些与用于定位 web 元素的 CSS 选择器相关的格式。

身份

当 CSS 选择器与 ID 属性一起使用时,在 HTML 标签和 ID 属性之间放置一个散列(

#

)符号。该符号仅用于 ID 属性。带有 ID 属性的 CSS 的一般语法是

<HTML_tag>#<ID_value>

这是 HTML 的例子。

<pid="press">Apress Publication </p>

您可以使用 CSS ID 定位器来定位 web 元素。

press=driver.find_element_by_css_selector('p#press')

有几种不同的方法可以用来代替前面的脚本,同样也可以定位 web 元素。

press=driver.find_element_by_css_selector("p[id = 'press']")

press=driver.find_element_by_css_selector("p#id='press'")
班级

CSS 选择器可以和 class 属性一起使用来定位 web 元素。HTML 标签和 class 属性之间使用了一个点(

.

)。带有类的 CSS 的语法是

<HTML_tag>.<class_name>

在下面的 html 代码片段中,CSS 选择器定位段落元素。

<html><body><p class="press ">Apress Publication </p>//HTML tag with multiple CSS classes
<p class="my-class text-justify">New York</p></body></html>

press=driver.find_element_by_css_selector('p.press')
'press'

变量使用 CSS 定位器定位 web 元素。一个点符号(

.

)将多个类组合成一个 CSS 选择器。它还区分了属性和值。

类似地,您可以找到具有多个 CSS 类的 web 元素。以下是写这个的各种方法。

press1 =driver.find_element_by_css_selector('p.container')

press1 =driver.find_element_by_css_selector('p.my_class')

press1 =driver.find_element_by_css_selector('.my_class')

press1 =driver.find_element_by_css_selector('my_class.container')

press1 =driver.find_element_by_css_selector('container.p')

所有 CSS 定位器脚本返回相同的 web 元素。

子字符串匹配大小写

Web 元素可以具有动态属性,并且对于不时出现的某些实例,往往会发生变化。要定位这些元素,默认 CSS 不是一个选项,因为它使用静态值作为 ID、类和名称。

CSS 选择器接受的符号在表 4-3 中描述。

表 4-4

带语法的元素定位器
|

元素定位器

|

句法

|
| — | — |
| 身份 | 按标识查找元素( ) |
| 名字 | 按名称查找元素( ) |
| 路径语言 | find_element_by_xpath() |
| 环 | find_element_by_link_text() |
| 部分链接 | find _ element _ by _ partial _ link _ text() |
| 标签名称 | 按标签名查找元素( ) |
| 类别名 | find_element_by_class_name() |
| CSS 选择器 | find_element_by_css_selector() |

表 4-3

带描述的子串字符
|

标志

|

字符名称

|

描述

|
| — | — | — |
| ^ | 停止 | 匹配字符串的前缀 |
| $ | 美元 | 匹配字符串的后缀 |
| * | 星号 | 使用子字符串匹配字符串 |
| : | 结肠 | 使用 contain()方法匹配字符串 |

所有的 substring 方法都应用在下面的 html 脚本片段中。这些子字符串与表 4-3 中描述的 id 相匹配。

<p id="apress_press"></p><p id="apress_123"></p><p id="123_apress_press"></p>

下面显示了使用子字符串定位的 CSS 选择器。

#Using Halt '^' for suffix
press3 =driver.find_element_by_css_selector("p[id^='123']")#Using Dollar '$' for prefix
press3 =driver.find_element_by_css_selector("p[id$='press']")#Using Asterisk '*' for all
press3 =driver.find_element_by_css_selector("p[id* ='_apress_']")#Using Colon ':' for contain method
press3 =driver.find_element_by_css_selector("p:contains('_apress_')")

当测试人员不知道完整的字符串模式时,这四个 substring 方法非常重要。

内部文本

带有

contains()

功能的冒号字符可以通过匹配 HTML 标签之间的文本来检索 web 元素。这段文字叫做内文

这个方法匹配开始和结束 HTML 标记之间的纯文本。使用页面上任何地方的文本来定位元素,这与所讨论的子字符串中的

contain()

函数相同。

<p>Apress</p>

press5 =driver.find_element_by_css_selector("p:contains('Apress')")

函数是用返回包含它的 web 元素的文本编写的。文本可以是完整的,也可以是部分的。

多个属性的 CSS 选择器

有时很难找到具有单一属性的 web 元素,因为不同的 web 元素具有相同的属性值。这可以通过使用 CSS Locator 和与特定 web 元素相关联的多个属性来解决。

以下是 HTML 代码示例。

<p class="container"id="apress" style="align-self: center;"></p>

下面是选择器的运行情况。

press4 =driver.find_element_by_css_selector("p[class= 'container'][id='apress'][style='align-self:center']")

在这个代码片段中,声明了多个属性及其关联的 tag 值来定位它。

子元素的 CSS 选择器

与 XPath 中讨论的子元素一样,CSS 选择器也可以在网页上定位子元素。为了识别或定位子元素,Selenium 提供了与 CSS 选择器一起使用的特殊符号。

如果 web 元素有一个子元素,那么使用大于号(

>

),其中 XPath 使用斜杠。

<div class="cars"><button id=Aston></div>

前面是带有一个子元素的 web 元素的示例。HTML 是

div.cars>a

,其中

div

是父节点,

button

是它唯一的子节点。

这是 HTML 示例。

<div id="cars"><a href="#aston_martin">Aston</a></div>

XPath 使用

//div//a

来定位 web 元素,而 CSS 选择器使用空格而不是斜线。

cars = driver.find_element_by_css_selector("div#cars a")

当存在多个没有 ID 或名称的子元素时,通过索引定位元素,也称为第个元素类型。它允许定位索引元素。索引从 1 开始。

<ol id="cars"><li>Aston Martin</li><li>BMW</li><li>Chevy</li><li>Dodge</li></ol>

这个有序列表有四个没有相应属性的子元素。为了定位这些元素,需要建立索引(从一个元素开始)。要定位的元素是第二、第三和第四个元素。

以下代码显示了使用 CSS 选择器定位的子元素。

#Locating second child element
car_no2 =driver.find_element_by_css_selector("ul#carsli:nth-of-type(2)")#Locating third child element
car_no3 =driver.find_element_by_css_selector("ul#carsli:nth-of-type(3)")#Locating last child element
last_cars=driver.find_element_by_css_selector("ul#carsli:last-child")

假设一个元素有 n 个子元素,而你不知道与之关联的子元素的数量。在这种情况下,后跟

'last-child'

关键字的 HTML 属性用于定位父元素的最后一个子元素。

链接定位器

链接文本定位器用于定位锚标签(

<a>

)

.

中可用的 web 元素,锚标签总是定义一个从一个页面切换到另一个页面的链接,也称为超链接。anchor 标签中的

href

属性指定了页面迁移到的目的地。

链接文本定位器试图匹配与锚定标签相关联的网页上可用的精确文本。链接文本定位器的语法是

find_element_by_link_text()

Note

通常,click()函数访问网页/应用中的链接。

HTML 代码中有链接定位器定位的锚标记。HTML 是

<div class="container">Categories
        <a href="python.html">Python</a><a href="web.html">Web Development</a><a href="machine.html">Machine Learning</a><a href="databases.html">Database</a></div>

网络驱动链接文本定位器定位分别与 python.html 和 database.html 的目的地地址相关联的文本 Python数据库

# Locate elements using link text
link1 =driver.find_element_by_link_text("Python")
link2 =driver.find_element_by_link_text("Database")

当锚标记中有多个具有相同文本的元素时,链接定位器检索第一个匹配的元素。

Note

链接文本和部分链接定位器都区分大小写。

部分链接定位器

这种部分链接定位器非常类似于链接定位器。唯一的区别是部分链接定位器试图匹配网页上锚标签中文本的子字符串。语法是

find_element_by_partial_link_text()

Note

使用两个链接定位器中的任何一个都可以访问任何链接,不管锚标记是在块 web 元素之内还是之外。

以下是相同 HTML 锚标记的部分文本 Python 代码。

# Locate elements using partial link text
link3 =driver.find_element_by_partial_link_text("Pyt")
link4 =driver.find_element_by_patial_link_text("Data")

PytData 是 Selenium WebDriver 的部分文本,用于定位锚标签内的元素。部分文本与网页上显示的文本相匹配;匹配时,它返回相关元素。类似地,当文本与多个 web 元素匹配时,第一个元素作为结果返回。

Note

当多个 web 元素出现在链接文本/部分链接文本定位器中定义了相同文本的网页上时,XPath 或 CSS 选择器用于定位其他 web 元素。

标签名称

一个网页/应用由许多 HTML 标签组成。这些标签因元素而异,但是允许在不同的 web 元素上使用相同的标签。在某些情况下,标签使您能够定位所选择的 web 元素。标记名的语法是

find_element_by_tag_name()

以下是相关 HTML 标记的标记名。

<html><head><title>Apress</title></head><body><h1>Python with Selenium</h1></body></html>

Selenium 标签名称定位器是

#Locating web element having <Title> tag
tag1 =driver.find_element_by_tag_name('Title')#Locating web element having <h1> tag
tag2 =driver.find_element_by_tag_name('h1')

当一个页面上有多个具有相同标签的 web 元素时,Selenium WebDriver 会定位第一个匹配指定标签的 web 元素。如果没有名为 title 或 h1 的元素,则会引发 no element 异常。

类别名

类名用于定位 web 元素,方法是在 Selenium 提供的类函数中声明类名。在 HTML 标记中很容易提供类名。类名定位器不是定位 web 元素的首选方式。语法是

find_element_by_class_name()

下面是一个简单的带有 Python 类名定位器的 HTML 示例。

<html><body><div class="my-class">Apress
<p class="text-justify">Python with Selenium</p></div></body><html>

下面是 Python 代码。

#For div element
class1 =driver.find_element_by_class_name('my_class')#For paragraph Element
class2 =driver.find_element_by_class_name('text-justify')

与多个元素的其他 web 定位器行为一样,类定位器返回同一类中许多其他元素中第一个匹配的 web 元素。当没有匹配的元素时,将引发异常。表 4-4 中给出了所有讨论过的定位器的语法。

Note

当 web 定位器无法定位 web 元素时,会引发 NoSuchElementException。

定位多个 Web 元素

当多个 web 元素具有相同的名称/ID/text/tag/class/link 时,Selenium WebDriver 将返回第一个匹配的元素。为了定位页面上所有可用的元素,Selenium 为每个定位器提供了一个函数/方法。每个定位器的语法在表 4-5 中列出。

表 4-5

定位所有 Web 元素的语法
|

元素定位器

|

句法

|
| — | — |
| 身份 | find_elements_by_id() |
| 名字 | 按名称查找元素( ) |
| 路径语言 | find_elements_by_xpath() |
| 环 | find_elements_by_link_text() |
| 部分链接 | find _ elements _ by _ partial _ link _ text() |
| 标签名称 | find_elements_by_tag_name() |
| 类别名 | find_elements_by_class_name() |
| CSS 选择器 | find _ elements _ by _ css _ selector() |

定位器返回的数据类型是列表。下面的例子列出了使用 CSS 选择器找到的所有元素。

import requests
from selenium import webdriver

driver = webdriver.Firefox(executable_path=r'C:\Users\ADMIN\Desktop\geckodriver.exe')

driver.get('https://apress.com')
images = driver.find_elements_by_css_selector("img")for image in images:if(requests.head(image.get_attribute('src')).status_code ==200):print("Element Found.")

列表中返回的所有元素都在循环中打印。定位器列出了 press 网页上所有可用的 web 元素。

定位器问题

存在 web 定位器无法定位元素的情况。接下来讨论定位器的常见问题。

属性变化

当对 web 元素执行某些操作时,它的行为总是会发生变化。这些动作可能是重复的,也可能每次都是新的。动态 web 元素开发了一种复杂的体验。一个例子是,像鼠标点击或页面重新加载这样的用户事件每次都可能导致不同的属性值。属性值的这些更改可能会阻止定位所需的 web 元素。要定位这些 web 元素,您必须确保定位器返回与其相关的 web 元素,不管发生了什么变化。

默认属性也由在网页/应用的内部框架中实现它们的开发者来改变。这使得能够分解页面上与该属性相关联的默认 XPath。要修正此类更改,您需要选择不同的定位器或再次检查路径。

没有 Web 元素

在许多情况下,web 元素是在某个事件发生或动作完成时创建的。只有在单击注销按钮后,注销元素才可用。类似地,在用户执行翻转或点击动作之后,菜单中的元素是可用的。

在这些情况下,事件会触发 web 元素的创建,因此必须在使用定位器之前执行操作。

Web 元素不可见

Web 元素在页面重新加载或用户执行操作后变得可用或可见,这就像没有 web 元素一样,但 web 元素存在于页面上。当应用定位器并且定位器不可见时,Selenium WebDriver 返回一个 NoElementFound 错误。

为了避免这些错误,web 元素通过等待变得可见,然后可以定位它们。有时 AJAX 脚本被用来隐藏元素,这些元素是使用等待来定位的。等待在第十章中解释。

测试用例不匹配

在某些时候,测试用例与定位器条件不匹配,或者测试用例的执行速度比 web 应用快,从而导致没有找到 Web 元素的错误。这是因为测试用例与 web 应用没有同步创建或显示 web 元素。

为了解决测试用例与网页/应用之间的同步丢失,测试用例暂停,直到满足所需的条件,这使得网页上的 web 元素可用。

iframe Web 元素

当一个 web 元素是一个 iframe,或者 iframe 中有一个元素时,定位这些元素就变得很困难,因为框架不容易访问。当有多个帧可用时,识别特定帧并不容易。即使它们可用,定位器也无法定位这些帧并返回错误。

要定位 iframe 或其中的元素,您需要识别页面上所有可用的框架,然后使用

switchTo.frame()

函数切换到要定位的框架。切换到指定的帧后,您可以使用任何定位器来定位 web 元素。

摘要

本章讨论了几种 web 定位器。ID 和名称定位器是最常用的,因为它们不容易被更改。下一个重要的定位器是 XPath。您看到了 XML 文档中 XPath 的结构。CSS 定位器是本章介绍的另一个重要的定位器。

下一章研究使用本章中讨论的定位器来定位超链接 web 元素。

标签: VKDoc

本文转载自: https://blog.csdn.net/wizardforcel/article/details/141068619
版权归原作者 绝不原创的飞龙 所有, 如有侵权,请联系我们删除。

“Python Selenium 测试教程(一)”的评论:

还没有评论