0


Python Selenium 测试教程(二)

原文:Python Testing with Selenium

协议:CC BY-NC-SA 4.0

五、导航

在上一章中,我们回顾了网页上可用的各种导航链接,这些链接可以使用 web 定位器来定位。还讨论了一些功能和特性。本章介绍了用于查找导航元素的 web 定位器应用。

在 web 开发中,超链接或链接是对数据的引用。这些数据以文档、视频、图像等形式嵌入到 web 元素中。导航可以定义为从一个位置迁移到另一个位置的活动。这种迁移可以在网页内进行,也可以在包含 web 元素的另一个网页上进行。导航过程是使用超链接完成的。

链接是显示在网页上的 URL(统一资源定位符),而超链接是通过在 HTML 中出现的锚标记之间放置链接来创建的。本章描述了定位超链接的各种方法,并设置了标准来测试其在嵌入了不同 web 元素的网页上的存在性。

用一个编程示例说明了定位超链接的机制。在网页导航的上下文中,您将了解超链接以及它们在网页上是如何定义的。

超链接

超链接主要与菜单、按钮、图像和文档相关联,通过使用鼠标动作(如单击)或提交表单,将用户引导到当前网页或另一个网页上的新位置/部分。在少数情况下,当表单完成时,按钮内会提供一个超链接来导航。

在网页上使用超链接有多种方式。超链接被合并到一个 HTML 锚标签中,该标签以

<a>

开始,以。任何文本都可以写在锚定标签中。该文本在浏览器中以默认的蓝色显示。超链接也被称为链接,可以使用 CSS 进行修改。语法是

<a href="URL">link text</a>

Note

超链接也被称为链接

下面是一个 HTML 的例子。

<div class="container">Selenium
<a href="python.html"id="python">Python</a><a href="elements.html"id="elements">Elements</a><a href="driver.html"id="driver">Driver</a><!—nth element➤
</div>

现在您已经了解了超链接,让我们看看如何在 Selenium 中使用 Python 测试它们。

测试超链接

Selenium 测试用例检查超链接是否断开。由于服务器错误,断开的链接不可达或不起作用。超链接是连接不同网页及其相关元素的媒介。

可以测试超链接的以下几点。

  • 链接是否可用
  • 通过从 HTTP 获取响应,链接是否正确导航到指定页面(断开的链接)
  • 对于依赖超链接的文档上传和表单提交
  • 网页上的许多链接使得手工测试非常耗时

Note

链接文本显示网页上超链接的存在。

Web 定位器提供了定位超链接的垫脚石。下面讨论定位超链接的各种方法。

按 ID 的超链接

可以使用锚标记中可用的 ID 来定位超链接。当网页有多种语言版本时,ID 是定位未更改的超链接的最佳方式。当找到超链接时,需要点击它来导航。

link1 =driver.find_element_by_id("python")

文本超链接

此语法匹配为链接指定的完整字符串。字符串可以是除英语之外的任何语言,英语有时会返回一个名为 NoSuchElementFound 的异常。

link2 =driver.find_element_by_link_text("Python")

部分链接的超链接

当需要在部分字符串中定位链接时,使用部分链接语法。该字符串与链接中存在的子字符串匹配。

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

XPath 超链接

可以使用 XPath 定位链接(参见第四章),如下所示。

link4 =driver.find_element_by_xpath("//a[@id= 'python']")

第 N 个超链接

当网页上有多个链接时,您可以使用索引值来选择链接。当需要使用索引时,链接应该在同一个标签下并按顺序排列。链接位于无法使用索引值识别或跟踪的标签下,因为标签会发生变化。

link5 = driver.find_element_by_xpath("//div/a[3]")

当链接的位置改变时,索引值也会改变,因此这种方法不太常用。

Note

添加或删除链接也会改变当前的索引值。

到目前为止,我们仅使用各种 web 定位器定位单个超链接。如果网页上有多个超链接,那么这些方法只返回其中第一个匹配的超链接。要定位所有 web 元素,请参考第四章中的表 4-5。

返回所有超链接

当一个网页上有多个链接时,CSS 选择器用于返回所有的链接。

links=driver.find_elements_by_css_selector("a")

在对超链接进行任何检查或验证之前,需要通过不同的定位器对其进行定位。要检查网页上是否存在超链接,可以使用验证表达式测试链接,这将在下面讨论。

检查有效的超链接

使用 HTTP 状态代码值来验证超链接是否有效。HTTP 发回一条对应于这些值的消息(见表 5-1 )。当链接断开时,HTTP 返回 404 错误(未找到链接或页面错误)。

表 5-1

HTTP 状态代码
|

HTTP 代码

|

描述

|
| — | — |
| Two hundred | 有效链接 |
| four hundred | 错误的请求 |
| Four hundred and one | 未经授权的 |
| Four hundred and four | 找不到链接/页面 |
| Five hundred | 内部错误 |

import requests
from selenium import webdriver

driver=webdriver.Firefox()
driver.get("http://apress.com/")
links=driver.find_elements_by_css_selector("a")for link in links:if(requests.head(link.get_attribute('href')).status_code==200):print("Link is Valid")else:print("Link is Invalid/Broken")

类似地,您可以通过将 CSS 选择器值更改为

img

来检查图像。

HTTP 状态代码及其错误描述在表 5-1 中列出。

检查损坏的图像

链接也可以与图像相关联。还可以通过与 HTTP 状态代码进行比较来检查超链接图像是否损坏,就像在只有链接的情况下一样。

import requests
from selenium import webdriver

driver =webdriver.Firefox()
driver.get("http://apress.com/")
images=driver.find_elements_by_css_selector("img")for image in images:if(requests.head(imageget_attribute('src')).status_code==200):print("Valid Image Link.")else:print("Invalid Image Link.")

可以使用 HTTP 协议中可用的状态代码来验证超链接(见表 5-1 )。现在,您已经知道了如何基于这些协议来验证超链接的存在,让我们来检查与超链接相关联的各个数据属性。

数据属性超链接

data 属性返回链接的文本值。当超链接元素未知时,该命令可以获取与超链接元素相关的数据属性值。

下面是一个 HTML 的例子。

<div class="hyper_links"><a href="python.html">Python</a></div>

下面是一个 Python 示例。

link1 =driver.find_element_by_css_selector("div.hyper_links a")print(link1.text)

这个测试用例返回 Python 中的数据属性,这是锚标记之间的一个属性文本值。

Note

表单或文档上载有与之相关的动态超链接。

摘要

本章定义了超链接,它对于迁移到网页上的另一部分或新网页至关重要。本章还介绍了测试超链接的主要方面以及定位超链接的不同方法。您了解了如何在网页上定位多个超链接。可以在超链接上执行许多验证。验证基于 HTTP 状态代码。

是时候探索更多可以定位和验证的独特的 web 元素了,比如超链接。由于选择的方法不同,验证有点独特。你将在下一章学习按钮。

六、按钮

用于跳转到 web 应用不同部分或页面的超链接定位器在上一章已经讨论过了。相同的 web 定位器用于跟踪按钮等用户界面元素。web 应用中有各种按钮,本章对此进行了介绍。

在任何与用户/客户端交互的 web 应用中,按钮都是用户界面的一部分。这些交互与特定的操作相关联,例如移动到下一页和提交表单。它们包括默认按钮、表单/提交按钮、单选按钮、复选框和选择列表。它们之间的差异取决于用法,这将在下面解释。

使用 Python 在 Selenium 上定位 HTML 按钮的类型,因为像这些按钮这样的 web 元素具有与之相关的特定功能。让我们从了解网页上的默认按钮开始。

默认按钮

默认按钮是 HTML 网页上最基本的类型。使用

<button>

标签创建一个默认按钮。下面的代码片段允许您创建一个默认按钮。图 6-1 显示输出。

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

图 6-1

默认按钮

<button id="default_btn"class="default" name="dft_btn" style="font-size:21px;">Default Button</button>

默认按钮可以具有各种功能,例如编辑、删除、创建、重置和清除。Selenium 在按钮上执行两个主要操作。

  • 选择(定位元素并单击)
  • 断言(检查按钮以及是否启用/禁用)

挑选

选择并单击按钮是在网页上定位按钮元素的一种方式。一个按钮在被点击时被激活,然后它执行分配给它的任务。

Note

在网页上找到按钮后,总是使用 click()方法选择按钮。

还有另一种单击按钮的方法,这将在本章后面讨论。可以通过以下任何方式选择默认按钮。

按 ID 选择

正如前面章节中所讨论的,ID 是一个惟一的属性,它用于方便地定位按钮元素。

#Method 1#Finding or Identifying Default Button
default_button=driver.find_element_by_id('default_btn')#Clicking on the button selected
default_button.click()#Method 2#Identifying & Clicking Default Button
default_button=driver.find_element_by_id('default_btn').click()

图 6-1 中默认按钮的 HTML 代码是定位按钮元素的来源。有两种方法。在第一种方法中,使用了两个函数,一个用于通过使用 ID 来识别默认按钮,然后通过使用

click()

函数来选择默认按钮(有关更多信息,请参见第三章)。

在第二种方法中,第一种方法中的相同函数被组合在一行代码中。本章的其余部分会用到它。第一种方法可读性更强,而第二种方法比较简短。由测试人员决定使用哪一个。

Note

这两种方法具有相同的功能和目的。

ID 是在开发人员编写代码时声明的,这使得测试人员在测试用例中使用更简单。

通过文本

这是按钮最基本的选择机制。在这种选择类型中,默认按钮是通过使用写入其中的文本来选择的,该文本在浏览器中可见。

图 6-1 显示了按钮的文本及其对应的 HTML 代码。在浏览器中编译时,文本总是出现在按钮上。在 HTML 代码中,文本放在开始和结束按钮标记之间。以下 Python Selenium 代码通过文本选择按钮。

#Using text ()
button_text=driver.find_elements_by_xpath
                        ("//button[text()='Default Button']").click()

按钮上的文本也可以使用 contain 函数和 text 函数来识别。

#Using contain () with text ()
button_text1 =driver.find_elements_by_xpath("//button[contains(text()='Default Button')]").click()
名叫

当 ID 不可用时,使用 HTML 中的 name 属性选择按钮。这就像通过名称定位 web 元素一样,如下所示。

default_button=driver.find_element_by_name('dft_btn').click()

当有多个按钮具有相同的名称时,将选择具有该名称的第一个按钮。

接下来,让我们看看另一种类型的按钮。

提交/表单按钮

提交按钮提交插入到表单中的数据。它位于表格的末尾。表单按钮通常是通过使用

<input>

标签或者将

submit

作为按钮或输入标签的类型来创建的。单击此按钮时,它会导航到另一个页面,或者在动态使用时会显示一条弹出消息。图 6-2 显示了一个提交按钮及其相应的源代码。

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

图 6-2

提交按钮

<h1> Employee Form</h1><form>
  Employee Name:<inputtype="text"id="ename" name="ename"><br><br>
  Employee Dept:<inputtype="text"id="dept" name="dept"><br><br><inputtype="submit" value="Submit Button"></form>

提交按钮只有在所有字段都被填充后才起作用,这使得它不同于默认按钮。

Note

只有当所有的表单元素都被填充时,表单按钮的 click()函数才是成功的。

按可见文本选择

选择提交按钮类似于选择默认按钮。按照相同的技术定位这些元素。下面是一个通过文本选择提交按钮的简单例子。

submit_text=driver.find_element_by_xpath
                        ("//input[@value'Submit Button']").click()

XPath 用于通过文本定位提交按钮,文本区分大小写。

作为按钮的图像

可以使用图像创建按钮。该图像为用户提供了定制的外观和感觉。

要将图像用作按钮,输入类型必须是带有定义该图像路径的

src

属性的

image

。它用于两种按钮类型。下面是一个使用图像创建的按钮的简单示例。

<form><inputtype="image"id="img" name="img_btn"
                                src="images/go.jpg" alt="Go"></form>

图 6-3 显示了一个用作按钮的图像。要选择一个图像按钮,可以在 Selenium 中使用下面的 Python 代码。

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

图 6-3

作为按钮的图像

#Image Button
image_button=driver.find_element_by_xpath("//input[contains
                                 (@src='images/go.jpg')]")

Note

图像可以作为提交或默认类型。

为按钮断言

按钮的两个主要断言方法是验证按钮元素在网页上的存在,以及检查该元素是否被禁用。

断言方法确定按钮是否出现在给定的网页上。按钮可以出现在网页上,但也可以被禁用,这使得按钮无法被单击。

click()

功能不能在禁用的按钮上操作。

检查按钮是否存在

按钮的存在让您知道按钮元素在指定的网页上是否可用。验证指定的属性或路径对于按钮是否仍然可用是非常重要的。

#Check if button is enabled or notif default_button.is_displayed():print("Element is Present")else:print("Element Not Present")
检查按钮是否已启用

当与 JavaScript 一起动态使用时,表单完成后,表单按钮被启用。只有极少数情况下禁用表单按钮;这可能是因为提交表单的日期已过,或者只能提交有限数量的表单。

#Check if button is enabled or notif default_button.is_enabled():print("Element is Enabled")else:print("Element Not Enabled")

在 Selenium 上使用 Python 中的

if-else

条件来检查它的存在以及按钮是被启用还是被禁用。这些验证对于所有按钮类型都是相同的。

接下来,让我们讨论单选按钮,它是网页上提供选项的最常用按钮之一。

单选按钮

当有多个选项可用时,使用单选按钮。每个单选按钮都有相同的名称属性。当从集合中选择一个单选按钮时,其他按钮会自动取消选择。对于组中单选按钮的数量或使用单选按钮的组的数量没有限制。

以下是图 6-4 所示单选按钮的 HTML 源代码。

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

图 6-4

单选按钮已选中和未选中

<h3>Select your Gender:</h3><div><inputtype="radio"id="male" name="gender" value="male"
checked><label for="male">Male</label></div><div><inputtype="radio"id="female" name="gender" value="female"><label for="female">Female</label></div><div><inputtype="radio"id="other" name="gender" value="other"><label for="other">Prefer not to Say</label></div>

图 6-4 显示当一个单选按钮被选中时,其中会出现一个黑点。未选中的单选按钮中没有点。这有助于您识别单选按钮是否被选中/选中。默认勾选,如 HTML 源代码所示。单选按钮中的选择不是强制性的。

Note

选择和选中是可以互换的。

属性值表示单选按钮的唯一值,该值仅在 HTML 代码中显示。用户无法在浏览器中看到它。该值被传输到服务器。

单选按钮有两个主要操作:选择和取消选择。接下来演示这两种操作。

选择单选按钮

有各种方法来选择需要在一组中测试的单选按钮,解释如下。

简单选择

要选择单选按钮,必须找到该元素,然后单击它。在这个方法中,使用 ID 属性选择单选按钮。

#Selecting female radio button
radio_button=driver.find_element_by_id("female")
radio_button.click()

选择的 ID 属性是 female,,它与 HTML 源代码中提供的单选按钮相关联。单击时,选定的单选按钮中会出现一个黑点。一个点可以定制成各种形状和颜色。主要目的是看到单选按钮被选中。

使用标签选择

标签是一个 HTML 标记,它写与表单 web 元素相关联的纯文本。纯文本写在标签的开始和结束标记之间。该文本也可用于选择单选按钮。

#Using label attribute with for
radio_button=driver.find_element_by_xpath("//label[@for='female']").click()

通过使用 XPath 和与之相关的属性值来选择 label 标记。点击功能在定位单选按钮后使用。

Note

单选按钮中的黑点表示该按钮已被选中。

取消选择/清除选择

单选按钮有两个相关的操作:一个是选择,另一个是取消选择。黑点仅在单选按钮被选中时可用。要清除选定的单选按钮,您需要选择另一个按钮,因为在同一个单选按钮集合中不允许多重选择。

从组中选择另一个单选按钮的方式与前面的选择类型相同。为了避免不必要的单选按钮选择,在某些情况下会引入默认选择。

Note

取消选择已经选定的单选按钮的唯一方法是从组/集合中选择另一个单选按钮。

单选按钮的断言

如果网页上有一组单选按钮,为了识别是否选中了某个按钮,或者为了确保指定的单选元素在网页上可用,就要使用断言。断言在测试单选按钮及其对应的操作中扮演着重要的角色。

断言单选按钮是否

有多种方法可以确定网页上的 web 元素是否是单选按钮。一种常见的方法是使用输入属性的属性值。如果输入类型是单选,那么 web 元素就是一个单选按钮。

#Locate Web element
radio_button=driver.find_element_by_id("female")#If stmt to check attribute valueif radio_button.get_attribute("type")=="radio":print("It is a Radio button")else:print("It is not a Radio button")

在这个例子中,使用来自

get_attribute( )

函数的

if

语句检查 ID 为女性的 web 元素的输入类型。

如果选中则断言

断言单选按钮是否被选中有两种方法。在第一种方法中,使用 select 函数;如果选中,则返回 true 作为布尔值,如果未选中,则返回 false。第二种方法检查单选按钮的属性值,即 HTML 源代码中的

checked

。选中时,它返回 true 如果未选中,则返回 false。

#Using Selection function
driver.find_element_by_id("female").is_selected()#Check using attribute function
driver.find_element_by_id("female").get_attribute("checked")

在某些情况下,单选按钮有默认选择。在图 6-3 中,默认单选按钮是第一个单选元素,文本为 male。可以使用返回布尔值的

if

语句来检查它。

radio_button=driver.find_element_by_id("female")if radio_button.get_attribute("checked")=="true":print('Radio Button is "Selected')else:print('Checkbox is Not Selected')

断言方法检查单选按钮是否被选中。但是按钮的定位不受使用 web 定位器定位的按钮类型的影响。

接下来,让我们检查复选框。

检验盒

复选框有一个与之关联的方框。当需要用户进行多项选择时,通常会使用它们。选择复选框没有限制。您可以选择同一组/集合中的所有复选框。但是,必要时也可以限制选择。

要在 HTML 中制作复选框,输入类型是

checkbox

。此属性类型让您知道断言期间复选框的存在。

<form><inputtype="checkbox"id="firefox" name="browser1" value=" b1" checked><label for="brower1"> Firefox</label><br><inputtype="checkbox"id="chrome" name="browser2" value="b2"><label for="browser2"> Chrome</label><br><inputtype="checkbox"id="opera" name="browser3" value="b3"><label for="browser3"> Opera</label><br><inputtype="checkbox"id="edge" name="browser4" value="b4"><label for="browser4"> Edge</label><br><br></form>

图 6-5 显示选中和未选中的复选框。当方框中出现勾号时,您知道复选框已被选中。

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

图 6-5

复选框已选中和未选中

选择/检查

选择复选框就像选择单选按钮。区别在于复选框允许多选,但是单选按钮只能选一个。复选框有各种相关的属性。通过单击它来选择它。

Note

复选框可以有多个与同一组相关的选择。

使用名称检查

可以使用 HTML 源代码中的 name 属性选择复选框,如下所示。

#Select Opera check button
check_button=driver.find_element_by_name("browser3").click()
使用 ID 检查

在这个方法中,ID 属性定位 checkbox 元素,然后使用 click 函数选择它。

#Select Edge check button
check_button=driver.find_element_by_id("edge")
check_button.click()

Note

当复选框被选中时,会出现一个勾号。

断言 If 复选框

checkbox

属性类型将元素标识为复选框,如下所示。

#Identify for Checkbox
check_button=driver.find_element_by_id("chrome")if check_button.get_attribute("type")=="checkbox":
        ˘        print("It is a Checkbox button")else:print("It is not a Checkbox button")

get attribute 函数在

if

语句中用于检查复选框元素的存在。

是否选中断言复选框

选中单选按钮的方式也适用于复选框。用于在网页上识别复选框的 Python Selenium 代码如下。

#Using Selection function
driver.find_element_by_id("firefox").is_selected()#Check using attribute function
driver.find_element_by_id("firefox").get_attribute("checked")

清除/取消选择/取消选择复选框

取消勾选选中的复选框就是取消选中取消选中,或者清除它。这三个术语可以互换使用。在 Selenium 上的 Python 中允许清除文本框,它用于测试复选框是否正常工作。在某些情况下,该复选框被禁用或设置为默认值,不允许您清除它。

在清除复选框之前,必须先选中它。这是通过再次使用相同的

click()

功能来完成的。要确定复选框是否被选中,可以使用 assert 函数。

#Clearing checkbox
check_button=driver.find_element_by_id('firefox')#if condition to check selectionif check_button.is_selected():#Clear using click()
        check_button.click()print('Checkbox clicked to deselected')else:print('Checkbox is not selected')

在这段代码中,如果复选框已经被使用

if

条件语句选中,则该复选框被识别;如果选中,则清除或取消选中它。

Note

只有当复选框被选中时,才能清除它。

除了清除方法之外,复选框中使用的所有方法都是单选按钮可用的方法。选择另一个选项后,单选按钮会自动清除。复选框则不是这种情况;因此,清除/取消选择是通过执行与选择相同的操作来完成的。

接下来,让我们讨论选择列表。

选择列表

最后一个按钮类型是选择列表。当用户可以选择单选或多选时,这种按钮类型既可以作为单选按钮,也可以作为复选框。选择列表创建下拉列表中列出的多个选项。可以从列表中选择一个或多个选项。通过分别组合

<select>

<option>

标签形成选择列表。它类似于一个下拉菜单。

<h1>Blood Group</h1><label for="blood">Choose Blood Group:</label><select name ="blood"id="bld_grp"><option value ="A"> A type</ option><option value ="B"> B type</ option><option value ="O"> O type</ option><option value ="AB"> AB type</ option><option value ="Bombay"> Bombay type</ option></select>

选择列表通常在表单标记中使用,但也可以单独使用。可以控制从列表中选择的选项数量。当从列表中只能选择一个选项时,它就像一个单选按钮。当可以从列表中选择多个选项时,它就像一个复选框。

图 6-6 和 6-7 显示了一个下拉菜单,其中列出了五种人类血型。单击下拉菜单可以打开它,这也允许您从中进行选择。

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

图 6-7

打开选择列表

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

图 6-6

单项选择列表

获得所有选项

您需要知道列表中所有可用的选项。这是通过使用下面的代码完成的。

s = driver.find_elements_by_tag_name("option")for option in s:print("Option is: %s"% option.get_attribute("value"))

如代码所述,

for

循环返回血型选择列表中的所有选项。

挑选

Selenium 中的 Python 提供了许多可供选择的方法。在从网页/app 中选择选择列表之前,你需要在 Python 中从

selenium.webdriver.support.select

中导入选择库。接下来讨论选择方法。

使用可见文本选择

下拉列表中可见的文本可用作选择选项的媒介。

#Importing Select Libraryfrom selenium.webdriver.support.select import Select

# First Select ID of drop-down
select_list=Select(driver.find_element_by_id('bld_grp'))# select by visible text
select_list.select_by_visible_text('O type')

在下拉/选择列表的选择过程中,首先定位下拉菜单。然后,创建一个实例来从列表中选择一个选项。可以使用几个属性来定位下拉列表,例如 ID 和 name。

按值选择

与每个选项相关联的值属性是不同的。这些属性值选择选项。选择列表中的可用值为 A、B、O、AB 和 Bombay。

# Select drop-down ID
select_list=Select(driver.find_element_by_name('blood'))# Select by visible text
select_list.select_by_value('O')

值属性区分大小写,并允许字母数字字符。

需要选择 O 型血。这是通过首先选择选项所在的下拉菜单来完成的,然后创建实例来选择指定的选项。

使用索引选择

选择列表中的选项具有 HTML 代码中未指定的索引值。Selenium 允许您使用这些索引值选择一个选项。索引值从 0 开始,与选择列表中的第一个选项相关。

# Selecting Drop-down
select_list=Select(driver.find_element_by_id('bld_grp'))# Selecting last option Bombay by index value
select_list.select_by_index('4')

索引值 4 选择下拉列表中的最后一个选项。要使用索引值选择选项,您需要知道下拉列表中可用选项的数量。

要选择下拉列表中的最后一个选项,请使用–1 索引值,这是 Python 中常用的。

# Selecting last option Bombay by index value
select_list.select_by_index('-1')

Note

如果列表不是使用 select 标记构建的,则不能使用 Selenium 上 Python 中的 select 方法。

取消选择/清除/取消选择

从列表中选择的选项可以通过清除它来恢复。取消选择/取消选择/清除(这两个术语是同义的)选择列表中的选项可以用与选择列表中的选项相同的方式来完成。该列表可以允许单项或多项选择。

取消选择/清除一个选定的

可以取消选择列表中的单个或多个选项。下面讨论取消选择/清除单个选项。

按可见文本取消选择

列表中可见的文本可以被接受为一个值,以便在选中时取消选中它。

#clear using index
clear= Select(driver.find_element_by_id('bld_grp'))

clear.deselect_by_index('Bombay')

使用可视文本功能取消选择最后一个选项 Bombay

按值取消选择

当指定的值与列表中的值属性匹配时,将取消选择该列表元素。

#clear by value
clear= Select(driver.find_element_by_id('bld_grp'))

clear.deselect_by_value ('O')

在这种情况下,可能会引发两种异常,一种是当定义的值不匹配时。第二个异常是在值匹配但没有选择列表元素时引发的,因为只有选择了列表,取消选择才起作用。

按索引取消选择

使用索引值取消选择列表中的选项。类似于选择具有索引值的选项,也可以清除/取消选择选项。

#clear by index
clear= Select(driver.find_element_by_id('bld_grp'))

clear.deselect_by_index('4')

如果选中,列表中的最后一个元素将被清除;否则,将引发异常。

多重选择列表

选择列表可以允许选择多个选项。HTML 源文件及其相应的输出如图 6-8 所示。在多项选择中,有七个选项可用,其中四个已被选中。选择这些选项的代码如下。不能使用 all_options,因为它选择所有可用列表。

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

图 6-8

多重选择列表

<h1>Fruit Salad</h1><label for="fruits">Choose Multiple Fruits:</label><select id="fruits" name="fruits" size="7" multiple><option value="apple">Apple</option><option value="banana">Banana</option><option value="cranberry">Cranberry</option><option value="dragonfruit">Dragon Fruit</option><option value="elderberry">Elderberry</option><option value="figs">Figs Fruit</option><option value="grapes"> Grapes</option></select><br><br><p>For Windows, hold the Ctrl button while selecting options. For Mac, hold the Command button while selecting options.</p>

在多项选择中,有七个选项可用,其中四个已被选中。代码中的选择如下。

ticks = Select(driver.find_element_by_id('fruits'))#Selecting Options in different ways
ticks.select_by_index(0)

ticks.select_by_value ('cranberry')

ticks.select_by_visible_text('Elderberry')

ticks.select_by_index(6)

核实

断言函数用于避免在找不到元素时出现异常,或者当元素未被选择时需要取消选择该元素,反之亦然。使用选项函数可以避免这种异常,选项函数可以让您知道列表的类型以及它是否被选中。

选择第一个选项

返回多选列表中选定的第一个选项或单选列表中当前选定的选项。

selected_list=Select(driver.find_element_by_id('bld_grp'))#Prints first selected option valueprint(selected_list.first_selected_option.get_attribute('value'))

print 语句打印列表中第一个选定的选项,如果没有选择任何选项,则返回一个错误。

选择所有选项

为了从列表中获得所有选中的选项,使用了一个名为

all_selected_options()

的函数。

selected_list=Select(driver.find_element_by_id('bld_grp'))#Returns all selected options
selected_list.all_selected_options()

它主要用于返回所有选定选项的多选列表中。

取消选择/清除所有选定的

此功能从下拉列表中清除/取消选择所有选定的选项。它主要用于列表中的多重选择。当没有多项选择可用时,将引发 NotImplementError 异常。

#Clear all selected
clear= Select(driver.find_element_by_id('bld_grp'))

clear.deselect_all()

为了清除列表中所有选中的选项,Selenium 提供了

deselect_all()

函数。

Note

如果列表不是使用 select 标记构建的,则不能使用 Selenium 上 Python 中的 select 方法。

摘要

本章解释了在第 3 和 4 章中讨论的鼠标/键盘动作和网络定位器,它们是用户界面上最常用的(即网络应用中的按钮)。web 定位器找到所有可用的按钮类型,并对它们执行相应的操作。

当找到默认按钮时,它只允许执行单击操作。提交按钮用于表单。单选按钮提供多个选项,但只允许其中一个选项。复选框允许多重选择。选择列表是一个按钮,根据其中的单项或多项选择进一步分为两种类型。每个按钮都有一个示例。

定位 UI web 元素,如框架和文本框,将在下一章讨论。

七、框架和文本框

前一章解释了如何定位默认、单选、复选框和选择列表等按钮。每个按钮都有与之关联的功能,如提交、选择或取消选择。按钮功能通过鼠标点击来实现(参见第三章)。本章讨论如何定位框架和文本框等 web 元素。它还解释了如何处理网页上的单个和多个框架。

本章还介绍了文本框类型、相关的 Selenium WebDriver 命令以及值插入。

内联框架

iframe 是 HTML 中另一种可用的 web 元素。它广泛用于嵌入与媒体相关的 web 元素(视频、图像等)。)在网页上。YouTube 视频和广告是网页嵌入视频和图像的两个最流行的例子。

框架可以嵌入任何 HTML web 元素。框架可以相互嵌套。Iframes 在开始时使用

<iframe>

标记,在结束时使用

</iframe>

标记。

Note

Iframes 的测试很重要,因为它们通常包含从其他网站或来源嵌入的 web 元素。

为了测试 iframe 中的 web 元素,您需要切换到那个特定的框架。很难定位 iframe,因为它是类似 DOM 的结构。当堆栈结构中有多个 iframe 元素时,切换到相关的 iframe 可以访问其中的 web 元素。

Note

一个内嵌框架是另一个用来描述 iframe 的术语。

在以前的 HTML 版本中,frameset 标签包含 frame 标签,但是 iframe 不需要这些标签。一个主要的区别是 iframe 中可以有嵌套的 iframe,这在框架中是不允许的。在 Selenium 中,框架和 iframes 被同等对待;因此,本章只测试 iframes。

HTML 中 iframe 的一个简单例子如图 7-1 所示。

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

图 7-1

单个 iframe

<iframe id="new_frame" name="apress" src="https://www.apress.com" height="300" width="300"></iframe>

前面的代码在 iframe 中显示了一个网站。您可以看到 iframe 包含到站点的链接。source (

src

)属性可以具有在网页之内或之外的 web 元素。高度和宽度可以是像素或百分比;这里使用了像素。

Note

HTML5 中不赞成使用 Frame 和 frameset 标记。而是使用 Iframes。

切换到 Iframe

与定位 web 元素类似,可以使用 switch 函数定位 iframes。当一个定义的 iframe 被切换时,那么只有测试可以在 iframe 中的任何 web 元素上执行。许多网页使用 iframe,因为在与 iframe 交互后不需要重新加载或刷新页面。以下部分描述了使用 Selenium 在 Python 中切换到 iframe 的方法。

使用 ID 切换

可以使用 ID 属性来定位 iframe,这是使用 switch 函数来完成的。Selenium 中的 Python 应用于前面的代码。ID 属性的值是

new_frame

# Switch to the frame with id attribute
driver.switch_to_frame("new_frame")

使用名称切换

name 属性也可以用来定位网页上的 iframe。

# Switch to frame with name attribute
driver.switch_to_frame("apress")

使用索引切换

如果网页包含一个以上的 iframe(见图 7-2 ),使用索引值切换到已定义的 iframe。这个指数值是由 Selenium 提供的。以下是多个框架的 HTML 代码。

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

图 7-2

多重 iframe

<center><div><h5>Frame0</h5><iframe id="new_frame0" name="apress" src="https://www.apress.com" height="150" width="400"></iframe></div><div><h5>Frame1</h5><iframe id="new_frame1" name="bing" src="https://www.bing.com" height="150" width="400"></iframe></div><div><h5>Frame2</h5><iframe id="new_frame2" name="wiki" src="https://www.wikipedia.org" height="150" width="400"></iframe></div>

下面是 Python 代码。

# Switch to frame 1
driver.switch_to_frame(0)# Switch to frame 2
driver.switch_to_frame(1)# Switch to frame 3
driver.switch_to_frame(2)

不建议使用此方法,因为在网页中添加或删除其他框架时,框架的位置可能会发生变化。

Note

Selenium 从 0(零)开始初始化网页上 iframe 的索引值。

作为一个元素切换

当网页上的多个 iframe 具有相同的 id 和名称时,切换到特定的框架是很困难的。在这些情况下,iframes 可以通过 web 元素来标识。ID 和 name 等 Web 元素用于切换到已定义的 iframes。

XPath、CSS 选择器或 classname 等 Web 元素定位器用于定位 iframes。其他 web 定位器,如 linkText 或 partialLinkText,不能用于定位 iframes。当一个网页上有多个 iframess 时,标签名 web locator 不是优选的,因为很难选择一个唯一的 iframe。

# Switch  to Iframes as Web Elements (Xpath)# Switch to frame 1
driver.switch_to_frame("//iframe[@src='https://www.apress.com']")# Switch to frame 2
driver.switch_to_frame("//iframe[@src='https://www.bing.com']")# Switch to frame 3
driver.switch_to_frame("//iframe[@src='https://www.wikipedia.org']")

使用 XPath 定位 iframe,这对于每个框架都是不同的。

Note

由于锚标记不可用,链接或部分链接文本不用于切换 iframe。

切换到主 Iframe

有两种方法可以切换到主框架,这将在下面讨论。

默认内容

对于默认内容,所有可用的 iframes 都被终止,并且控件被切换回网页。当控件返回到页面时,不会与 iframe 中的 web 元素进行交互。

driver.switch_to.default_content()

父框架

对于父框架,当前的 iframe 被终止,并且控制被切换到它的父 iframe。如果没有对应于所选或当前 iframe 的父 iframe,则当前 iframe 被终止,并且控制被切换回网页。

driver.switch_to.parent_frame()

有等待的帧

当处理 iframes 时,您可以使用等待来切换到任何帧,因为这些帧由于外部源或链接而需要更多的时间来加载。下面是几个等待的例子。

  • Frame ID :
  • Frame Name :
iframe=WebDriverWait(driver,5).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"iframe_id"))
  • Frame XPath :
iframe2 =WebDriverWait(driver,5).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"iframe_name"))
  • Frame CSS :
iframe3 =WebDriverWait(driver,5).until(EC.frame_to_be_available_and_switch_to_it(By.XPATH,"iframe_xpath"))
iframe4 =WebDriverWait(driver,5).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"iframe_css_selectors"))

现在让我们继续讨论文本框。

文本框

文本框接受文本形式的用户输入。该文本存储在数据库中或由网页使用。有两种类型的文本框:单行和多行。

单行文本框

单行文本框通常被视为登录选项,其中登录名和密码都需要单行文本。文本框是单行的矩形形状;它有各种尺寸。HTML 中的输入标签定义了一个单行的文本框。下面是一个单行文本框的 HTML 示例。如图 7-3 所示。

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

图 7-3

单行文本框

<h1>Single Line Textbox</h1><label for="book">Book Name:</label><inputtype="text"id="book1" name="book">

单行文本框通常用在表单中或用作网页上的搜索框。谷歌搜索引擎是最常用的单行文本框。

多行文本框

当文本使用多行时,就需要多行文本框。多行文本框通常用于电子商务网站上的评论框或脸书上的帖子。大小可以根据行和列(高度和宽度)而变化。为了定义一个多行文本框,使用了

<textarea>

标签。图 7-4 显示文本区域和其中的文本值。下面是它的 HTML 代码。

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

图 7-4

多行文本框

<h1>Textarea</h1><label for="book">Book Name:</label><br><textarea id="book2" cols="50" rows="5">
Python Selenium Sujay.</textarea>

可以拖动右下角的文本区域来增加其大小。可以通过指定相应的参数来限制 textarea 的大小。

Note

不可编辑的文本框仅用于显示与其关联的值。

插入值

textbox 和 textarea 用于从用户处获取值。这些值存储在数据库中,或者对照数据库中的值进行验证,以相应地授权或应用限制。要测试 textbox 或 textarea 是否可以接收输入,您需要向它发送值。这是通过在带有 Selenium 的 Python 中使用

send_keys

函数来完成的。

#Import librariesfrom selenium import webdriver

#Open Firefox browser
driver=webdriver.Firefox()#Navigate to URL
driver.get("http://www.apress.com")#Find Search box (Single Line Textbox)
text_box=driver.find_element_by_name("query")#String Value to be Inserted i.e. query in search box
text_box.send_keys("Python Testing with Selenium")#Insert Value
text_box.submit()# Quit Firefox
driver.quit()

Note

在 textbox 和 textarea 中插入值在很大程度上是相同的;唯一的区别是包含它们的行。

从 Textbox 和 Textarea 获取值

一个测试用例可以检索文本框或文本区域的输入值。在出现错误的情况下,检索与这些框相关的任何值,以便与预期值进行比较。以下是 textbox 和 textarea 的 Python 代码。

#For Textbox
text_box=driver.find_element_by_id('book1').get_property('value')print(text_box)#ForTextarea
text_area=driver.find_element_by_id('book2').get_property('value')print(text_area)

摘要

本章简要介绍了 iframe 和 iframe 的定位方法。存在多个 iframes 出现在一个网页上的情况。通过一个例子解释了切换到特定 iframe 的过程。

文本框大致分为两种类型——单行和多行。多行文本框也称为 textarea。您学习了使用定位器识别这两种类型的文本框。您还了解了在两种文本框类型中插入值以及检索与指定文本框相关联的值。

下一章是关于验证 web 元素的。

八、断言

在前面的章节中,您学习了定位 web 元素,如链接、按钮、框架和文本框,以及与它们相关的测试用例。在自动化 web 应用或页面的任何测试用例之前,您需要验证它,这是通过提供关于 web 元素的条件来完成的。这种验证或检查是通过使用断言函数来完成的,这些函数在 Selenium 和 Python 中都有提供。

断言允许您使用 web 元素的分配值来验证或检查预期值。分配的值可能是与之相关的任何属性,而期望值是我们在测试中比较的值。本章解释了 Python 在 Selenium 中提供的断言及其类型和自动化任何测试用例的用法。这些断言也是 unittest 框架的一部分,这将在本书后面的章节中讨论。在这一章中,我们研究了几个由 Selenium 在 Python 中提供的断言方法,这使得编写测试用例时调试更加容易。

断言的需要

断言是一种主要用于检查或验证与 web 元素相关的特定条件或测试用例的方法。断言函数或方法给出两个结果:通过或失败(即布尔术语中的真或假)。

只有当测试条件中的两个参数或值相同,并且在运行时没有引发异常时,测试用例才会通过。类似地,当两个值不相同时,测试用例失败,并引发 AssertionError 异常(仅当使用 assert 函数时)。

断言主要用于测试测试用例中的单个 web 元素,也称为单元测试。它对相关测试用例的结果进行报告。该报告通知开发人员与测试用例相关的任何错误或缺陷。

其余部分按用法组织断言类型。每种类型都有一个简短的定义,包括语法和示例代码。

基本资产

在 Selenium 中,Python 提供了一些基本的断言,用于评估其中定义的两个值。测试用例是成功还是失败,取决于函数的结果。当测试用例失败时,会引发异常。还可以提供可选的文本消息。

assertTrue

assertTrue

测试给定的条件或结果是否为真。当条件为真时,测试用例通过,当条件为假时,测试用例失败。它验证单个值,后跟一条文本消息,这是可选的。下面是它的语法示例。

assertTrue(value1, text_msg=null)import unittest
from selenium import webdriver

classtest_case1(unittest.TestCase):deftest1(self):
                s1 ="Python"
                s2 ="Ruby"# Verifying Numbers
                self.assertTrue(s1== s2,"It's not a Match.")if __name__ =="__main__":
        unittest.main()

assertFalse

当指定的条件为假时,

assertFalse

方法通过测试。当条件为真时,测试失败,并引发异常。它使用单个值。下面是它的语法示例。

assertFalse(value1, text_msg=null)deftest2(self):
        s1 ="Python"# Verifying Numbers
        self.assertFalse(s1 =='Ruby',"It’s a Match.")

分类

assertIs

函数将 value1 与 value2 进行匹配,看它们是否相同。当两个值相同时,测试用例通过;否则,将引发异常。下面是它的语法示例。

assertIs(value1, value2, text_msg = null)deftest_lang(self):
        lang="Python"#Check lang
        self.assertIs("Selenium", lang,"value do not Match.")

资产广告

assertIsNot

验证值 1 和值 2 是否相同。如果它们不相同,那么测试用例通过;如果它们相同,测试用例失败。下面是它的语法示例。

assertIsNot(value1, value2, text_msg = null)deftest_lang(self):
        lang="Python"#Check lang
        self.assertIsNot("Python", lang,"Value is Match.")

阿瑟酮

assertIsNone

检查给定的条件或值是否为空。如果为空,则测试用例通过;如果它不为空,那么该函数将引发一个异常。下面是它的语法示例。

assertIsNone(value, text_msg = null)

这里,值可以是表达式、条件或参数。

deftest(self):
        color=None# Check if value is null.
                self.assertIsNone(color,"color is not null")

资产声明无

如果指定的条件或值不为空,则

assertIsNotNone

方法通过测试用例;否则,测试用例失败。下面是它的语法示例。

assertIsNotNone(value, text_msg = null)deftest(self):
        color="green"# Check if value is not null.
        self.assertIsNotNone(color,"color is null")

资产实例

检查一个给定值是否是一个类的实例。如果对象不是实例,则会发生异常。下面是它的语法示例。

assertIsInstance(value, cls, text_msg = null)

assertNotIsInstance

当给定值是类的实例时,引发异常。如果值不是类的实例,那么相应的测试用例通过。下面是它的语法示例。

assertNotIsInstance(value, cls, text_msg = null)

比较断言

断言函数可以相互比较。使用以下断言比较两个值是大还是小。

assertequals

assertEqual

方法比较两个值。如果两个值相等,那么测试用例通过,如果不相等,那么测试用例不能引发异常。通过和失败是根据函数返回的布尔值来确定的。下面是它的语法示例。

assertEqual(value1, value2, text_msg=null)

语法定义了两个用于比较的值,如果两个值不匹配,可能会显示一条文本消息。文本消息可以为空,因此可以选择使用。下面是一个测试页面标题值的简单示例(可执行路径与前面章节中描述的相同)。

import unittest
from selenium import webdriver

classtest_case1(unittest.TestCase):deftest1(self):
                driver=webdriver.Firefox()
                driver.get("https://apress.com")

                title1 =driver.title
                title2 ="Apress Home"# Verifying Page Title
                self.assertEqual(title1, title2,"Title Page do not Match.")if __name__ =="__main__":
        unittest.main()

assertNotEqual

assertNotEqual

assertEqual

功能相反。当两个值不相等时,测试用例通过;否则,测试用例失败。下面是它的语法示例。

assertNotEqual(value1, value2, text_msg=null)deftest2(self):
        num1 =7
        num2 =5# Verifying Numbers
        self.assertNotEqual(num1, num2,"Numbers Match.")

资产更大

assertGreater

检查第一个值是否大于第二个值;如果是,那么测试通过,否则测试用例失败。下面是它的语法示例。

assertGreater (value1, value2, txt_msg = null)

assertgreatereequal

assertGreaterEqual

函数检查值 1 是否大于或等于值 2;如果是,那么测试用例通过。下面是它的语法示例。

assertGreaterEqual (value1, value2, txt_msg = null)

无资产

使用

assertLess

,当值 1 小于值 2 时,测试用例通过,当值 1 小于值 2 时,测试用例失败。文本消息是可选的。

assertLess

的行为与

assertGreater

功能相反。下面是它的语法示例。

assertLess (value1, value2, txt_msg = null)

assertlesseequal

只有当 value1 小于或等于 value2 时,

assertLessEqual

方法才通过测试用例;否则,测试会导致失败,并引发异常。下面是它的语法示例。

assertLessEqual (value1, value2, txt_msg = null)deftest_cmp(self):
        num1 =7
        num2 =5#Check num1 is greater
        self.assertGreater(num1, num2,"num1 is less.")#Check num1 is greater than or equal to
        self.assertGreaterEqual(num1, num2,"num1 is less.")#Check num1 is less
        self.assertLess(num1, num2,"num1 is greater.")#Check num1 is less than or equal to
        self.assertLessEqual(num1, num2,"num1 is greater.")

集合断言

集合是特殊类型的数据存储,其中可以存储多个元素。该集合包括用 Python 语言构建的列表、元组、集合、字典等等。

列表

assertListEqual

函数允许我们比较两个列表。当两个列表包含相同的元素时,测试用例通过;如果列表没有相同的元素,那么测试用例失败。下面是它的语法示例。

assertListEqual(list1, list2, text_msg=null)deftest_list(self):
        list1 =["python","selenium","apress"]
        list2 =["python","selenium","apress"]#Check elements in both lists
        self.assertListEqual(list1, list2,"Lists don't Match.")

元组

元素的比较在两个元组之间进行。当这两个元组中有相同的元素时,那么函数返回一个布尔值 True,这意味着测试用例通过,反之亦然。下面是它的语法示例。

assertTupleEqual(tuple1, tuple2, text_msg=null)deftest_tuple(self):
        tuple1 =("python","selenium","apress")
        tuple2 =("python","selenium","apress")#Check elements between two tuples
        self.assertTupleEqual(tuple1, tuple2,"Tuples don't Match.")

设置

与前面的函数类似,

assertSetEqual

函数比较两个集合之间的元素。如果两个集合包含相同的元素,那么测试用例通过,反之亦然。下面是它的语法示例。

assertSetEqual(set1, set2, text_msg=null)deftest_set(self):
        set1 ={"python","selenium","apress"}
        set2 ={"java","selenium","apress"}#Check elements from two sets
        self.assertSetEqual(set1, set2,"Sets don't Match.")

词典

assertDictEqual

方法中,一个字典中的所有可用元素都与另一个字典匹配。如果所有元素都相同,那么测试用例是成功的;如果元素不相同,那么测试用例就是失败的。文本消息是可选的。下面是它的语法示例。

assertDictEqual(dict1, dict2, text_msg=null)deftest_dict(self):
        dict1 ={"lang":"python","tool":"selenium","publication":"apress","year":"2020"}
        dict2 ={"lang":"kotlin","tool":"selenium","publication":"apress","year":"2020"}#Check elements from two sets
        self.assertDictEqual(dict1, dict2,"Dictionaries don't Match.")

主张

assertIn

检查值 1 在值 2 中是否可用。如果该值可用,那么测试用例将无任何异常地通过。下面是它的语法示例。

assertIn(value1, value2, text_msg = null)

Note

集合断言用于检查集合中 web 元素的可用性。

资产净值

assertIn

函数一样,

assertNotIn

检查 value2 中是否存在 value1。如果存在,那么测试用例失败;如果它不存在,那么测试用例是成功的。下面是它的语法示例。

assertNotIn(value1, value2, text_msg = null)

下面的程序使用

assertIn()

assertNotIn()

函数检查任何给定收集数据中元素的可用性。

deftest_item(self):
        collection=set(["Python","Selenium","Apress"])#Check for Python element in a set
        self.assertIn("Python", collection,"Element is not available in the set.")#Check for Java element in a set
        self.assertNotIn("Java", collection,"Element is available in the set.")

Note

有些断言函数没有包含在内,因为它们在 Python 的新版本中已被弃用。

这就完成了所有可以在 Python 中用于使用 Selenium 创建的测试用例的断言函数。

摘要

您学习了测试用例中的断言。您还了解了不同的断言技术,比如基本断言、比较断言和带有多个函数的集合断言。

本章中解释的断言评估或验证 web 应用中的 web 元素。断言允许您对测试用例中出现的调试问题做出报告,以便开发人员可以快速解决它们。

下一章讨论 Selenium 中的各种异常以及处理它们的方法。

九、异常

最后一章讨论了断言,它评估测试用例中的特定条件。这一章主要关注在 Python 和 Selenium 中发生的异常。首先,您需要知道什么是 Selenium 异常以及它们的各种类型。在 Selenium 测试用例中,有几个方面会引发异常。每个异常都是由特定的原因引起的,本章对此进行了解释。Selenium 提供了许多内置的异常,这些异常会导致测试用例的终止。为了避免这些不寻常的终止,应该处理一个异常,以便测试用例遵循正常(默认)的执行流程。在这一章中,我们将研究不同类型的异常,引发这些异常的原因,以及如何在 Selenium 测试用例中处理异常。让我们从定义异常和测试用例中需要异常开始。

什么是异常?

当程序的执行被异常事件中断时,就会发生异常。当一个异常被引发或者发生时,测试用例停止它的正常流程并被终止。

为什么要使用异常?

以下是在 Selenium 中使用异常的一些原因。

  • 它将默认测试用例代码与错误处理代码分开。
  • 没有必要在测试用例的每一点检查错误。
  • 异常允许您通过任何处理错误来完成测试用例的默认执行。
  • 它使得测试用例中的错误报告更加容易。
  • 使用异常时,很容易对错误进行分类。

Selenium 的异常

既然您已经考虑了测试用例中出现异常的原因,那么让我们看看在执行测试用例时 Selenium 中可能出现的所有异常。每个异常都用触发异常的事件来定义。

ConnectionClosedException

当 web 驱动程序断开连接时,Selenium 会引发这个异常。

ElementClickInterceptedException

当单击元素的命令因需要单击的请求元素被隐藏或隐藏而未正确执行时,会发生此异常。

ElementNotInteractableException

在这种异常类型中,已定义的 web 元素不能与另一个元素交互或指向另一个元素,即使它存在于文档对象模型(DOM)中。

ElementNotSelectableException

无法选择 web 元素,即使它存在于 DOM 中。这引发了一个异常。这个动作属于 Selenium 中的 select。异常更可能发生在要选择的按钮中,如单选按钮、复选框等。

ElementNotVisibleException

当某个元素出现在网页上,但对要在其上执行的操作不可见时,会引发此异常。元素的不可见性是由于 HTML 标签中的隐藏类型,或者某些操作需要首先执行。这个异常通过使用 wait 来解决,wait 等待一个元素变得可见。

ErrorInResponseException

当服务器端出现错误时,会发生此异常。这在与远程服务器或 Firefox 扩展通信时很常见。下面列出了其中的一些错误。

  • 400-badrequest
  • 401–未经授权
  • 403–禁止
  • 405–方法不允许
  • 409–冲突
  • 500–内部服务器错误

ErrorHandler(错误处理程序)。未知服务器异常

当服务器给出一个没有堆栈跟踪的错误时,这个异常被用作占位符。

ImeActivationFailedException

当 IME 引擎无法激活时,会引发此异常。IME 是输入法引擎的缩写。它通常与被 Selenium 作为输入的中文、日文或多字节字符一起使用。IBus 是支持像 anthy 这样的日本引擎的输入框架的一个例子。

ImeNotAvailableException

当设备上不支持 IME 时,会出现此异常。

insecurexertificateexception

TLS(传输层安全性)证书如果过期或无效,会在用户端引发此异常。

InvalidArgumentException

当传递无效或扭曲的参数时,Selenium 会引发这个异常。

InvalidCookieDomainException

当试图为其他域或 URL 而不是当前 URL 添加 cookie 时,Selenium 会调用这个异常。

invalidcoordonateexception

当用户需要在相应的 web 元素上执行动作或操作时,当定义的坐标不正确或无效时,该异常被激活。当移动 web 元素或用提供的坐标单击按钮的鼠标操作失败时,会引发此异常。

InvalidElementStateException

当 web 元素被禁用或无法执行指定给它的操作时,Selenium 会引发这个异常。例如,当所有相应的字段都已填充时,提交按钮才起作用,如果您试图事先单击提交,则会引发此异常。

InvalidSelectorException

当用户没有从网页返回指定的 web 元素时,将引发 InvalidSelectorException。它更有可能是由 XPath 引发的,因为路径无效或被更改,这意味着定位 web 元素失败。

InvalidSessionIdException

如果测试用例中的会话 ID 不活动、已经过期或者不存在,那么 Selenium 会引发这个异常。

InvalidSwitchToTargetException

当需要放置或切换到目标位置的网页上没有框架或窗口元素时,会发生此异常。

JavascriptException 异常

如果 JavaScript 文件或代码片段的执行有问题,就会调用这个异常。

jsoneexception

当在未创建会话的情况下获得会话功能时,会发生此异常。

MoveTargetOutOfBoundsException

当目标 web 元素或鼠标移动无法指向定义的边界时(即,超出网页的边界,或者它是无效的),此异常由 ActionChains()保留。

NoAlertPresentException

当弹出警告(例如,警告框、提示框、确认框等)时,会发生这种异常。)目前不可用。JavaScript 引导警告弹出窗口。引发此异常的其他原因包括警告框需要更多时间来加载或在当前阶段不可用,JavaScript 在浏览器端被阻止,或弹出窗口已经关闭。

NoSuchAttributeException

如果 web 元素无法返回其属性,则会引发此异常。这是测试用例中最罕见的 Selenium 异常之一。您可以通过了解 web 元素是否有关联的属性来避免这种异常。

也可以通过更新 DOM 中可能已经改变的属性值来处理该异常。

NoSuchCookieException

当浏览器当前上下文的活动文档中存在的 cookie 中定义的 cookie 没有匹配项时,将引发此异常。

NoSuchElementException

这是 Selenium WebDriver 测试用例中最常见的异常。当 web 定位器无法从网页中跟踪或定位已定义的 web 元素时,此异常被撤销。找不到 web 元素,因为 DOM 不包含它,或者它无效。

当定义的 web 元素在 web 页面上不可用时,Selenium 抛出 NoSuchElementFoundException。以下任何原因都可能导致此异常。

  • web 元素定位器值不正确或不匹配。
  • 加载页面需要很长时间,所以 web 元素没有定位。
  • 在测试执行时,web 元素在网页上不可用或不可见。

NoSuchElementException 是通过从八个可用的定位器中选择一个特定的 web 定位器来处理的(更多信息见第四章)。它还指定等待以确保 web 元素已经完全加载。

NoSuchFrameException

当您希望切换到当前不可用的框架时,会发生此异常。当刷新页面时切换框架的具体细节发生变化,或者信息与任何可用的框架都不匹配,或者 web 元素不是框架,或者加载时间不足时,就会发生这种情况。

nosuchwindowsexception

当应该在浏览器窗口中执行某些操作时(如切换到已定义的窗口或移动窗口的位置),如果窗口当前不存在,则会引发此异常。当窗口尚未加载并且试图对其进行操作时,也会发生这种情况。

NoSuchContextException

在移动测试中,ContextAware 引发了这个异常。

屏幕截图异常

当 Selenium 无法对网页进行截屏时,就会出现这个异常。该异常在引发时会将屏幕截图变成黑色图像。

staleelemontreferenceexception

当 web 元素由于被删除或处于稳定状态而不再存在于 DOM 中时,会发生此异常。这很常见,因为现在大多数 web 元素都是动态的。一个简单的例子是,刷新页面可能导致已定义的 web 元素不可用。

这个异常可以由 XPath 处理,XPath 处理 web 页面上的动态 web 元素。

超时异常

当执行没有在定义的时间框架内完成时,Selenium 会返回一个超时异常。使用等待来处理异常,这使您能够为执行提供更多的时间。时间值应该是标准的,以便在测试用例的进一步执行中没有延迟。

UnableToSetCookieException

当 Selenium WebDriver 无法设置 cookie 时,会引发此异常。

UnexpectedAlertPresentException

当网页上出现意外警报时,Selenium 会发出此警报,这是由于警报(即弹出窗口)中的 Python 命令停止。

意外的标记名异常

当支持类无法定位或找到预期的 web 元素时,会发生此异常。它更常见于下拉元素中。

UnknownMethodException

当请求的 Selenium 命令与已知的 URL 匹配,但与为该 URL 指定的方法不匹配时,会引发此异常。为了避免这种异常,您需要在测试用例中声明方法之前检查它。

WebDriverException

这是一个基类 Selenium WebDriver 异常,当 WebDriver 和目标 web 浏览器不兼容时会调用它。所有其他异常都属于这个基类。

异常处理

现在您已经知道了 Selenium 测试用例中出现的所有异常,让我们来研究处理它们的正确方法。异常出现后继续执行测试用例的过程称为异常处理处理异常。处理异常是为了执行和避免测试用例不必要的终止。

异常会妨碍下一个需要执行的有效语句,因此,Selenium 提供了一个处理异常的解决方案。可以通过跳过或忽略引发的异常来处理异常,因此,测试用例继续以其正常流程执行。

Note

处理异常减少了调试时间。

使用 Python 中的 try-except 方法处理异常。通过定义一个异常,当它在测试用例执行期间出现时,你可以忽略或者跳过它。异常处理有助于减少测试用例中的错误失败,并导致找到实际的 bug(如果有的话)。接下来讨论测试用例中异常处理的一些常见例子。

超时异常

web 元素定位器等待指定的时间,以便加载完整的页面。

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By

driver=webdriver.Firefox(executable_path=r'C:\folder\geckodriver.exe)
driver.get("https://apress.com")try:# Web driver waits for 5 seconds to locate web element
        WebDriverWait(driver,5).until(EC.presence_of_element_located((By.ID,"query")))except TimeoutException:# When loading page takes more timeprint("Taking more time to load.")

找不到元素

这是 Python 和 Selenium 中最常见的异常之一。

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

driver=webdriver.Firefox()
driver.get("https://apress.com")try:
            web1 =driver.find_element_by_id("privacy")
        web1.click()except NoSuchElementException as exception:print("Web Element is not Available in the given Web Page.")

陈旧元素

当 web 元素不再出现在 DOM 中时,就会出现陈旧元素。此异常在以下程序中引发,方法是在 web 元素首次提交一段时间后提交该元素。忽略或跳过试图终止测试用例的已处理异常。类似地,任何异常都可以被处理。同样的方法也可以用于测试用例中可能出现的多个异常。

from selenium import webdriver
from selenium.common.exceptions import StaleElementReferenceException
import time
driver= webdriver.Firefox(')
driver.get('http://apress.com')

driver.find_element_by_name('query').send_keys('python selenium')whileTrue:try:
                      s=driver.find_element_by_class_name('search__submit')
                s.submit()
                time.sleep(2)
                s.submit()except StaleElementReferenceException:print('Stale Exception is Skipped.')break
driver.quit()

Note

Selenium 中的每个异常的处理方式与 Python 中的相同(即使用 try-except 方法)。

异常处理终止测试用例的忽略或跳过。任何异常都可以处理。同样的方法也可以用于测试用例中可能出现的多个异常。

摘要

本章介绍并定义了 Selenium 异常。您了解了在测试用例中出现 Selenium 异常的原因。

定义了几乎所有在 Selenium 测试用例中可能出现的异常,并解释了它们在测试执行期间出现的原因。在上一节中,您学习了在一个示例测试用例中处理最常见的异常。

下一章将讨论等待,在等待中,测试用例被延迟一段特定的时间。

十、等待

第九章是关于测试用例中可能出现的各种异常,你已经看到了如何处理它们。本章简要介绍了 Selenium 上 Python 中使用的等待。等待可以最小化测试用例运行期间触发的大多数异常。

有时,在执行特定操作后或经过一段时间后,web 元素才可用。这些操作是在用户端通过表单、按钮或鼠标/键盘操作完成的,这些操作将用户导航或重定向到另一个网页。

这些操作也可以使用 AJAX 来执行,AJAX 是 JavaScript 和语言的组合(因此缩写来自异步 JavaScript 和 XML)。在代码中使用 AJAX 或 JavaScript 来控制 web 元素的可用性或可见性。AJAX 或 JavaScript 的广泛使用是因为它

  • 更新 web 应用/页面,无需再次加载
  • 加载页面后请求服务器数据
  • 加载页面后接收服务器数据
  • 将数据发送到服务器,无需再次刷新/加载页面

接下来解释等待的必要性。

Note

AJAX 可以以纯文本或 JSON 文本的形式发送或接收数据。

为什么需要等待?

大多数 web 应用/页面都是通过 AJAX 或 JavaScript 使用 AngularJS、NodeJS、ReactJS 等框架制作的。这些应用通过刷新(重新加载)页面或加载页面来加载网页元素。为了定位这样的 web 元素,Selenium 提供了等待。

Python 脚本被编写来自动化用户的交互。考虑一个简单的例子:当一个表单被填写,点击提交按钮,页面被重定向。提交之后,web 元素就可用了。隐藏 web 元素是使用 JavaScript 或 AJAX 完成的。要使这些 web 元素可见,您必须等待执行特定的操作或加载页面。因为元素是隐藏的,所以无法解决引发的任何错误或异常。Selenium 等待主要用于克服重定向 web 应用时出现的这类错误。等待还通过定位 web 元素来处理异常的数量。

以下是 web 元素无法定位的众多原因中的几个。

  • 由于使用 AJAX 或 JavaScript 时时间的变化,所有的 web 元素还没有完全加载到 web 页面上。
  • 只有当用户执行指定的操作时,web 元素才可用。
  • 对网页的响应有延迟。
  • 网页/应用表现不佳,web 元素无法加载。

等待的类型

等待处理来自 Selenium WebDriver 的 ElementNotVisibleException 和 NoSuchElementException 之类的异常。等待由在网页上定位 web 元素的条件来定义。根据条件的不同,Selenium WebDriver 通常将等待分为三种类型:隐式、显式和流畅。

隐形的

在隐式等待中,WebDriver 会在调用 NoSuchElementFound 异常之前等待(轮询 DOM)一段指定的时间。默认等待时间为零秒。它可以在页面上可用的任何 web 元素上实现。

Note

DOM 代表文档对象模型,是 HTML 和 XML 的接口。

等待条件在 Python 脚本中定义,该脚本查找给定页面上指定 web 元素的存在。直到在条件脚本中设置的时间范围内找到 web 元素,WebDriver 才会继续。如果在设定的时间内没有找到元素,就会引发异常。

等待 web 元素的概念来自 Watir 工具。清单 10-1 展示了一个隐式等待的例子。(请注意路径在章节 1 和 2 中有解释。)

# Import Selenium Librariesfrom selenium import webdriver
from selenium.webdriver.common.keys import Keys

# Time frame set for 10 seconds
timeout =10# Creating Firefox driver instance
driver = webdriver.Firefox()# Calling Implicit wait function
driver.implicitly_wait(timeout)#driver.implicitly_wait(10) Time frame can diretly be set# Go to URL www.apress.com
driver.get("http://apress.com")print("It's an Implicit Wait")# Retrieving ID element
new_element = driver.find_element_by_id("query")# Type "Python with selenium" in search bar
new_element.send_keys("Python with selenium")# Submit text in search bar
new_element.submit()# Close Firefox browser
driver.quit()

Listing 10-1Implicit Wait

在本例中,web 驱动程序等待 10 秒钟,通过 ID 查找/定位 web 元素。测试人员确定时间范围。web 驱动程序尝试在定义的时间范围内搜索指定的元素;如果找到,web 驱动程序将返回该元素,提交指定的文本,并关闭浏览器。如果找不到元素,则会引发异常。

Note

隐式等待用于不立即可用的 web 元素。

明确的

满足特定条件后,页面上的 web 元素被加载或变得可用。这些条件可能因元素而异。在这种情况下,不能使用隐式等待,因为它只能等到元素被加载或出现。等待时间不能急剧增加,这可能会导致更多的时间来执行整个脚本。这导致了隐式等待的改进版本的使用,它被称为显式等待

考虑一个动态网页,它有一个只能在用户交互后加载的元素。如果使用隐式等待,它会等待指定的时间,然后因为元素不存在或不可见而引发异常。显式等待用于定位这些元素。显式等待在使用时定义了两个条件:WebDriver 等待和 Python 类中的 ExpectedConditions。

第一个条件是 WebDriver wait,它定义了一个等待一定时间的整数值。第二个条件定义了指定 web 元素的预期条件。ExpectedConditions 是 Selenium WebDriver Python 库中可用的预定义函数/方法。当满足预期条件时,WebDriver 不会等待定义的等待完成,而是继续执行 Python 脚本中的下一条代码指令。这是隐式和显式等待的主要区别。

Note

显式等待的默认轮询频率是 500 毫秒(0.5 秒),不能更改。

# Import all Necessary Selenium Librariesfrom selenium import webdriver
Missing python timeout exception
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException

# Creating Firefox driver instance
driver = webdriver.Firefox()# Go to URL www.apress.com
driver.get("https://www.apress.com")# Time frame set for 10 seconds
timeout =10try:# Returns ID element, when successful
        new_element = WebDriverWait(driver,timeout).until(
         EC.presence_of_element_located((By.ID,"query")))# Type "Python with selenium" in search bar
    new_element.send_keys("Python with selenium")# Submitting text in search bar
    new_element.send_keys(Keys.ENTER)except TimeoutException:print("Failed to locate search bar")finally:
    driver.quit()# Closing Firefox browser
driver.quit()

Listing 10-2Explicit Wait

在清单 10-2 中,时间范围被设置为 10 秒。驱动程序访问 Apress web 页面,它的 ID 属性定位一个元素。在指定时间内检查 web 元素,如果可用,则返回;否则,会遇到异常。因此,如果使用循环,可能需要无限长的时间才能满足条件。当存在页面重定向时,循环失败。当设置等待时,它定期检查,并在定位到元素或时间结束时退出流程。

Note

混合隐式和显式等待会导致无限长的等待时间。

显式等待使用定位 web 元素所需的 ExpectedConditions。接下来将描述这些情况。

Python 类中常用的预期条件

预期条件通常会自动执行测试脚本。这些条件是经常遇到的,主要用于显式等待。

ExpectedConditions 是在 Selenium 包库中用 Python 预定义的。在合并之前,您需要安装并导入 Python 脚本。预期条件在

expected_condition

模块中可用。导入库文件的 Python 脚本是

from selenium.webdriver.support import expected_conditions as ec

Note

ec 是 expected_conditions 的缩写形式,通常在 Python 语言中使用。

预期条件是针对 web 元素的。下面描述了通常用于自动化测试的预期条件。

  • 警报存在它检查在指定的时间范围内网页上是否出现警告。如果存在,它返回警报对象;否则,它会引发 Selenium 常见异常,如 TimeoutException。
  • **element _ located _ selection _ state _ to _ be(ui _ locator,is _ select)**它检查 web 元素是否可以被 web 页面上的任何定位器定位,并检查其选择状态。如果在设定的时间范围内找到具有所需选择状态的指定 web 元素,则不会引发异常。
  • **元素 _ 定位 _ 待选(ui_locator)**它检查 web 元素在时间范围内是否处于网页上的选中状态。可以使用第四章中提到的任何定位器来定位该元件。找不到元素时会引发异常。
  • 元素 _ 选择 _ 状态 _ 目标(ui _ 元素,is _ 选择)类似于element _ located _ selection _ state _ to _ be;唯一的区别是,在这种情况下,传递的是 web 元素,而不是标识它的定位器。它还在返回元素之前检查所标识元素的状态。
  • **element _ to _ be _ clickable(ui _ locator)**在这种情况下,web 元素应该处于一种不可见的状态,允许在其上使用单击机制。这个异常条件一直等到设定的时间,并尝试使用定位器定位指定的可点击 web 元素。如果没有遇到具有点击的元素,则调用异常。
  • 待选元素(ui_element)它检查 web 元素是否处于选中状态。它类似于被定位为被选中的的元素,但是在这个方法中,通过直接传递 web 元素来代替定位器,元素处于选中状态。当在设定的时间限制内未找到元素时,将引发异常。
  • **frame _ to _ be _ available _ and _ switch _ to _ it(ui _ locator)**它在设定的时间内检查网页上的指定框架并切换到该框架。如果该帧存在,则给定的驱动程序会切换到该帧,否则会引发超时异常。
  • **不可见元素定位(ui 定位器)**它检查指定的元素在定义的时间内在 DOM 中是否可见/不可见。这个元素可以是定位器,也可以是 web 元素。当 web 元素不可见或从 DOM 中删除时,没有超时或没有这样的元素异常。
  • **标题 _ 是(标题)**它检查指定的文本是否在网页的标题中。文本区分大小写。文本必须与网页标题完全匹配;否则,它会返回超时异常。
  • (ui _ element)的过时状态这个方法一直等到一个元素不再与 DOM 相关联。web 元素已经变旧或者已经从 DOM 中删除,因为部分或整个页面,或者只有元素被刷新,这在 Selenium 中被称为陈旧元素。如果没有找到陈旧的元素,那么它返回一个布尔值 False。
  • **text _ to _ be _ present _ in _ element(ui _ locator,inner_text)**它检查指定的文本是否存在于所识别或定位的 web 元素中。在这里,定位器找到元素,然后检查文本。如果元素中存在文本,则不会引发异常。
  • **text _ to _ be _ present _ in _ element _ value(ui _ locator,value)**它检查文本是否出现在时间范围内元素的 value 属性中。如果不存在,则引发两个异常之一(即超时或 NoSuchElement)。
  • **标题 _ 包含(标题 _ 文本)**它检查指定的文本是否出现在网页的标题中。如果部分或全部指定文本出现在网页标题中,则返回匹配的网页标题。文本区分大小写。
  • **可见性 _of(ui_element)**它检查 DOM 页面中的 web 元素是否可见。这里,可见性意味着元素不仅具有大于 0(零)的高度和宽度,而且元素是否被显示。该方法检查 web 元素在 DOM 页面上是否处于隐藏状态,或者是否由于超时或用户交互而对用户可见。如果元素不可见,将引发异常。
  • **可见性 _ of _ 所有 _ 元素 _ 定位(ui_locator)**它检查所有的 web 元素是否都存在于 DOM 中并且可见。元素应该以大于零的高度和重量显示。它返回所有定位的可见 web 元素;否则,将引发异常。考虑一个包含七个元素的网页;只有四个可见,其他三个处于隐藏状态。在这种情况下,web 驱动程序会在分配的时间段内等待其他三个元素可见。如果元素没有从隐藏状态切换到可见状态,则会引发超时异常。
  • **visibility _ of _ any _ elements _ located(ui _ locator)**它检查是否至少有一个元素在 DOM 中注册并且在 web 页面上可见。可见性标准是相同的;例如,在一个 web 页面中,有五个 web 元素出现在 DOM 中并且可见。WebDriver 试图在三个中找到一个来满足预期的条件。如果在 DOM 中没有可见的或注册的,则会引发异常。
  • **可见性 _ 元素 _ 位置(ui _ 定位器)**它分别检查由定位器跟踪的、在 DOM 中注册的以及可见的元素。显示 web 元素,并且其尺寸(即,高度和重量)大于零。
  • **不可见元素定位(ui 定位器)它检查 web 元素在 DOM 中是否存在,在 web 页面上是否可见。这是visibility _ of _ element _ located(ui _ locator)**的一个对比条件。当一个元素仍然可见,并且在设定的时间限制内没有切换到隐藏状态时,就会引发异常。
  • **新窗口已打开(当前句柄)**在这种情况下,会打开一个新窗口,并且窗口句柄的数量会增加。
  • **目标窗口数量(窗口数量)**它检查窗口的数量是否有一定的值。该值是在给定方法中定义的整数。当该值与窗口数匹配时,不会引发异常。
  • **url_changes(网址)**在这种情况下,当前的 URL(统一资源定位符)被新的 URL(即预期的 URL)改变。当网页的 URL 改变时,则使用该条件。当前和预期的 URL 不应相同。如果当前 URL 没有更改,则会引发异常。该 URL 区分大小写。
  • **url_contains(网址)**检查定义的 URL 字符串以查看当前 URL 是否包含它的任何部分。如果它与子字符串匹配,则不会调用任何异常。该字符串区分大小写。
  • **url_matches(url)**它用定义的 URL 字符串检查当前 URL。该条件检查当前 URL 中的确切模式。如果检测到该模式,则不调用异常。该模式可以是正则表达式。
  • *url_to_be(url)它根据预期的 URL 检查当前的 URL。它类似于 URL_*****matches(URL)**方法,但唯一不同的是,该方法使用实际的 URL,而不是正则表达式格式。当前 URL 应该与预期的 URL 完全匹配,否则会引发异常。
  • **所有元素的存在位置(定位器)**它检查网页中是否存在至少一个使用定位器识别的元素。同一个网页上可以出现多个 web 元素,它们通过定位器进行匹配。如果返回匹配的 web 元素列表,则不会引发异常。匹配元素的数量是在一个时间范围内完成的。
  • **定位元素的存在(定位器)**它检查 web 元素在 web 页面 DOM 上是否可用。DOM 上元素的可用性不一定是可见的。定位器找到元素。当 DOM 中不存在某个元素时,会引发异常。

Note

在一个时间框架内设定预期条件;如果不满足条件,则调用超时异常。如果元素存在,则可以自定义时间约束。

隐性和显性的区别

既然你已经回顾了隐式和显式等待,让我们看看它们之间的区别,如表 10-1 中所提供的。

表 10-1

隐式和显式等待的区别
|

隐形的

|

明确的

|
| — | — |
| 它可以应用于网页/应用上所有可用的 web 元素 | 仅适用于用户与之交互的元素 |
| 无法定义预期的条件 | 需要定义预期的条件 |
| 元素只能通过等待指定的时间来定位 | 在设定的时间内检查预期条件以定位元素 |
| 不能忽略指定的时间 | 当满足预期条件时,剩余时间被忽略 |

流利的

流畅等待设置 web 元素的等待时间和轮询频率。定期检查 web 元素,以在设定的时间范围内定位。轮询频率和时间范围可以根据需要变化。流畅等待尝试在指定的时间范围内定期跟踪/定位 web 元素,或者直到找到该元素。

当使用 AJAX 的 web 元素花费的时间比平时长,或者在较短的时间间隔内变得可见时,流畅的等待非常有用。它允许您忽略任何异常。这些例外是用时间间隔和轮询频率指定的。清单 10-3 给出了一个流畅等待的简单 Python 脚本。

Note

对于实时 web 应用,建议使用流畅的等待,因为轮询会获得更新的结果。

# Import all Necessary Selenium Librariesfrom selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import ElementNotVisibleException
from selenium.common.exceptions import ElementNotSelectableException

# Creating Firefox driver instance
driver = webdriver.Firefox()# Go to URL www.apress.com
driver.get("https://www.apress.com")# Time frame set for 10 seconds
timeout =10# Fluent Wait with time interval, poll frequency and exceptions
wait = WebDriverWait(driver, timeout,
        poll_frequency=1,
        ignored_exceptions=[ElementNotVisibleException, ElementNotSelectableException])# Retrieving ID element
new_element = wait.until(EC.presence_of_element_located((By.ID,"query")))# Close Firefox browser
driver.quit()

Listing 10-3Fluent Wait

时间范围为 10 秒的流畅等待和轮询频率设置为每秒检查一次 web 元素,直到超时,如程序 3 所示。如果引发类似 NoSuchElementExceptions 和 ElementNotVisibleException 的异常,也将被忽略,最后关闭浏览器。

Note

可以定制流畅等待中的轮询频率。

摘要

等待为页面刷新/加载以及 web 应用中 web 元素的不适时出现提供了真正的解决方案。本章解释了 Selenium 支持的不同类型的等待(隐式、显式和流畅)。

隐式等待提供了在 web 应用中定位指定 web 元素的时间范围。显式等待有时间框架和预期条件;任一个都被验证为满足定义的条件。还详细解释了显式等待中出现的预期条件。最后,通过实例探讨了流畅等待。fluent wait 是 wait 中的一个改进版本,因为它支持时间限制、轮询频率,并且在其功能中可以忽略一个异常。

需要一个模型来整合我们到目前为止学到的各种测试用例。这个模型是建立在页面对象上的。下一章将讨论页面对象和与之相关的模型。

标签: VKDoc

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

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

还没有评论