Python Selenium 详解:实现高效的UI自动化测试

        落日余辉,深情不及久伴。大家好,在当今软件开发的世界中,自动化测试已经成为保障软件质量和快速迭代的重要环节。而在自动化测试的领域中,UI自动化测试是不可或缺的一部分,它可以帮助测试团队快速验证用户界面的正确性和功能性。

        然而,UI自动化测试也面临着许多挑战,比如复杂的页面结构、动态加载的内容、不稳定的元素定位等等。为了有效应对这些挑战,测试人员需要借助强大的工具和框架。在这方面,Python与Selenium的结合成为了一种常见且强大的选择。

        本文将深入探讨Python和Selenium在UI自动化测试中的应用。我们将从基础开始,介绍Python和Selenium的安装和设置,然后逐步深入到各种功能和技巧。我们将通过丰富的示例代码和详细的解释,帮助测试人员更好地理解和利用这些工具,从而实现高效、稳定的UI自动化测试。

一、Python和Selenium介绍

1、Python

        Python是一种高级编程语言,以其简单易学、功能强大和丰富的生态系统而闻名。由于其简洁的语法和广泛的应用领域,Python已经成为了软件开发、数据科学、人工智能等领域的首选语言之一。Python具有丰富的第三方库和工具,可用于各种用途,包括网络开发、数据分析、自动化测试等。

2、Selenium

        Selenium是一个用于自动化Web应用程序测试的工具。它提供了一组工具和API,使开发人员能够模拟用户在Web浏览器中的操作,如点击按钮、输入文本、提交表单等。Selenium最初是为Web开发人员设计的,但随着时间的推移,它成为了自动化测试领域的标准之一。

3、Python和Selenium的问题解决

        Python和Selenium的结合解决了UI自动化测试中的许多挑战和问题。在传统的手动测试中,测试人员需要反复进行相同的操作,这样既费时又容易出错。而通过使用Python编写Selenium脚本,可以自动化执行这些操作,从而提高测试效率、减少人为错误,并且可以在短时间内快速验证大量的测试用例。

4、安装Selenium

在命令行中运行以下命令来安装Selenium:

pip install selenium

5、下载WebDriver

        Selenium需要与浏览器驱动程序(WebDriver)一起使用,以便模拟用户在浏览器中的操作。需要根据要测试的浏览器类型下载相应的WebDriver。例如,如果要测试Chrome浏览器,可以下载ChromeDriver;如果要测试Firefox浏览器,可以下载geckodriver。将WebDriver下载并将其添加到系统路径中,以便Selenium能够找到它。

Chrome WebDriver下载地址(浏览器版本114之前):

https://chromedriver.storage.googleapis.com/index.html

Chrome WebDriver下载地址(浏览器版本123以后): 

Chrome for Testing availability

Firefox GeckoDriver下载地址:

https://github.com/mozilla/geckodriver/releases

下载完成后,需要将驱动文件设置在环境变量中,如果是linux系统,可以参考下面文章。

在Linux上使用Selenium驱动Chrome浏览器无头模式

二、第一个Selenium脚本

        当准备好开始编写您的第一个Selenium脚本时,您需要确保已经按照前面提到的步骤安装了Python、Selenium和适当的浏览器驱动程序。现在,让我们编写一个简单的脚本来打开一个网页:

# 导入Selenium库中的webdriver模块
from selenium import webdriver# 创建一个浏览器对象,这里我们选择Chrome浏览器,也可以选择其他浏览器
driver = webdriver.Chrome()# 打开一个网页,这里以百度为例
driver.get("https://www.baidu.com")# 在网页上查找一个元素,例如百度的搜索框
search_box = driver.find_element_by_name("wd")# 在搜索框中输入关键词
search_box.send_keys("Python Selenium")# 提交搜索
search_box.submit()# 等待一段时间,让搜索结果加载完成(这里使用隐式等待,等待最多10秒)
driver.implicitly_wait(10)# 打印当前网页的标题
print("网页标题:", driver.title)# 关闭浏览器
driver.quit()

解释一下这个简单的脚本:

  1. 首先,我们导入了Selenium库中的webdriver模块,它包含了浏览器的各种操作功能。

  2. 接着,我们创建了一个WebDriver对象,这里我们选择了Chrome浏览器,并将其赋值给driver变量。

  3. 然后,我们使用get()方法打开了一个网页,这里我们选择了百度搜索首页。

  4. 接下来,我们使用find_element_by_name()方法找到了百度搜索框的元素,并将其赋值给search_box变量。

  5. 我们使用send_keys()方法在搜索框中输入了关键词“Python Selenium”。

  6. 然后,我们调用了submit()方法,提交了搜索请求。

  7. 使用implicitly_wait()方法设置了隐式等待,等待搜索结果加载完成,最多等待10秒。

  8. 最后,我们打印了当前网页的标题,然后调用了quit()方法关闭了浏览器。

三、元素定位

        元素定位是Selenium中的一个重要概念,它指的是在网页上找到需要操作的元素的过程。在Selenium中,有多种元素定位方法可供选择,每种方法都有其特点和适用场景。

下面我们将详细介绍几种常用的元素定位方法:

1、通过ID定位

        通过ID定位是Selenium中最常用的一种定位方法之一,因为ID是HTML元素的唯一标识符,每个元素都应该具有唯一的ID。因此,通过ID定位是一种快速有效的定位方法。

使用find_element_by_id()方法来通过元素的ID定位元素,其基本语法如下:

element = driver.find_element_by_id("element_id")

其中,element_id是要定位元素的ID值。

通过ID定位的示例:

假设我们有以下HTML代码:

<div id="login_form"><input type="text" id="username" name="username" placeholder="请输入用户名"><input type="password" id="password" name="password" placeholder="请输入密码"><button type="submit" id="login_button">登录</button>
</div>

我们可以使用Selenium通过ID定位用户名输入框,其ID为username,示例代码如下:

username_input = driver.find_element_by_id("username")

同样地,我们可以使用ID定位登录按钮,其ID为login_button,示例代码如下:

login_button = driver.find_element_by_id("login_button")

注意事项:

  1. 确保元素具有唯一的ID:ID在HTML中应该是唯一的,如果有多个元素具有相同的ID,则会导致定位失败或定位到错误的元素。

  2. ID定位是一种高效的定位方法:由于ID是唯一标识符,因此使用ID定位通常比其他定位方法更快速有效。

2、通过类名定位

        通过类名定位是Selenium中常用的一种定位方法,特别适用于那些具有相同class属性的元素。在HTML中,一个元素可以拥有一个或多个class属性,每个class属性可以包含一个或多个类名,类名之间用空格分隔。通过类名定位的基本思想是根据元素的class属性值来定位元素。

使用find_element_by_class_name()方法来通过元素的类名定位元素,其基本语法如下:

element = driver.find_element_by_class_name("class_name")

其中,class_name是要定位元素的类名。

通过类名定位的示例:

假设我们有以下HTML代码:

<div class="login-form"><input type="text" class="username-input" name="username" placeholder="请输入用户名"><input type="password" class="password-input" name="password" placeholder="请输入密码"><button type="submit" class="login-button">登录</button>
</div>

我们可以使用Selenium通过类名定位用户名输入框,其类名为username-input,示例代码如下:

username_input = driver.find_element_by_class_name("username-input")

同样地,我们可以使用类名定位登录按钮,其类名为login-button,示例代码如下:

login_button = driver.find_element_by_class_name("login-button")

注意事项:

  1. 类名定位仅适用于单一类名:如果元素有多个类名,而您只知道其中一个类名,那么只能通过该类名来定位元素,无法同时使用多个类名来定位。

  2. 类名定位不适用于复合类名:如果元素的class属性值包含了多个类名,例如class="class1 class2 class3",那么类名定位将不适用,需要使用其他定位方法,如CSS选择器或XPath。

3、通过标签名定位

        通过标签名定位是Selenium中一种简单而常用的定位方法,它通过元素的标签名来定位元素。在HTML文档中,每个元素都有一个标签名,例如<div><input><a>等,通过标签名定位可以方便地找到页面上所有具有相同标签名的元素。

使用find_element_by_tag_name()方法来通过元素的标签名定位元素,其基本语法如下:

element = driver.find_element_by_tag_name("tag_name")

其中,tag_name是要定位元素的标签名。

通过标签名定位的示例:

假设我们有以下HTML代码:

<div class="login-form"><input type="text" name="username" placeholder="请输入用户名"><input type="password" name="password" placeholder="请输入密码"><button type="submit">登录</button>
</div>

我们可以使用Selenium通过标签名定位用户名输入框,其标签名为input,示例代码如下:

username_input = driver.find_element_by_tag_name("input")

注意,这将返回页面上第一个<input>标签元素,如果有多个<input>标签元素,将只定位到第一个。

注意事项:

  1. 标签名定位返回第一个匹配的元素:如果页面上有多个相同标签名的元素,那么标签名定位将返回第一个匹配的元素,如果需要定位到其他匹配的元素,可以使用其他定位方法或结合使用定位方法来定位。

  2. 标签名定位适用于通用元素:标签名定位适用于那些没有唯一属性(如ID、类名)的通用元素,但对于具有唯一属性的元素,建议使用更精确的定位方法,以提高定位的准确性和稳定性。

4、通过名称定位

        通过名称定位是Selenium中常用的一种定位方法,特别适用于那些具有name属性的元素。在HTML中,一个元素可以具有一个name属性,通过该属性可以为元素指定名称。通过名称定位的基本思想是根据元素的name属性值来定位元素。

使用find_element_by_name()方法来通过元素的名称定位元素,其基本语法如下:

element = driver.find_element_by_name("element_name")

其中,element_name是要定位元素的名称。

通过名称定位的示例:

假设我们有以下HTML代码:

<form id="login_form"><input type="text" name="username" placeholder="请输入用户名"><input type="password" name="password" placeholder="请输入密码"><button type="submit">登录</button>
</form>

我们可以使用Selenium通过名称定位用户名输入框,其名称为username,示例代码如下:

username_input = driver.find_element_by_name("username")

同样地,我们可以使用名称定位密码输入框,其名称为password,示例代码如下:

password_input = driver.find_element_by_name("password")

注意事项:

  1. 名称定位仅适用于单一名称:如果元素有多个name属性,而您只知道其中一个名称,那么只能通过该名称来定位元素,无法同时使用多个名称来定位。

  2. 名称定位不适用于没有name属性的元素:如果元素没有name属性,那么名称定位将不适用,需要使用其他定位方法,如ID、类名、标签名等。

5、通过链接文本定位

        通过链接文本定位是Selenium中常用的一种定位方法,特别适用于那些由<a>标签表示的链接元素。在HTML中,链接元素通常用<a>标签表示,其中的文本内容即为链接文本。通过链接文本定位的基本思想是根据链接文本来定位链接元素。

使用find_element_by_link_text()方法来通过链接文本定位元素,其基本语法如下:

element = driver.find_element_by_link_text("Link Text")

其中,Link Text是要定位的链接文本。

通过链接文本定位的示例:

假设我们有以下HTML代码:

<a href="https://www.example.com">Example Link</a>

我们可以使用Selenium通过链接文本定位链接元素,其链接文本为Example Link,示例代码如下:

example_link = driver.find_element_by_link_text("Example Link")

注意事项:

  1. 链接文本定位匹配完整文本:使用链接文本定位时,Selenium会精确匹配指定的文本内容,因此必须确保文本内容与页面上显示的完全一致,包括大小写和空白字符。

  2. 链接文本定位不适用于部分文本:如果需要匹配部分文本,可以考虑使用部分链接文本定位方法,后面会介绍。

6、通过部分链接文本定位

        通过部分链接文本定位是Selenium中常用的一种定位方法,特别适用于那些链接文本太长或不完整的情况。有时候,页面上的链接文本可能过长,或者只需要匹配部分文本来定位链接元素。通过部分链接文本定位的基本思想是根据链接文本的部分内容来定位链接元素。

使用find_element_by_partial_link_text()方法来通过部分链接文本定位元素,其基本语法如下:

element = driver.find_element_by_partial_link_text("Partial Link Text")

其中,Partial Link Text是要定位的部分链接文本。

通过部分链接文本定位的示例:

假设我们有以下HTML代码:

<a href="https://www.example.com">Example Link</a>

我们可以使用Selenium通过部分链接文本定位链接元素,其链接文本为Example,示例代码如下:

example_link = driver.find_element_by_partial_link_text("Example")

注意,这将匹配所有包含Example的链接文本,不论它们位于链接文本的什么位置。

注意事项:

  1. 部分链接文本定位匹配包含指定文本的所有链接:使用部分链接文本定位时,Selenium会匹配包含指定文本的所有链接文本,因此可能匹配到多个链接元素。

  2. 部分链接文本定位可能不唯一:如果页面上存在多个包含相同部分文本的链接,部分链接文本定位可能不唯一,需要结合其他定位方法来定位唯一的元素。

7、通过XPath定位

        XPath(XML Path Language)是一种用于定位XML文档中节点的语言,它在Selenium中被广泛用于定位Web页面上的元素。XPath通过节点的层级关系或属性来定位元素,具有很强的灵活性和表达能力。

XPath有两种类型:绝对路径和相对路径。

  1. 绝对路径: 绝对路径从文档的根节点开始,描述了从根节点到目标节点的完整路径。它以斜杠(/)开头,例如:/html/body/div[1]/input[1]

  2. 相对路径: 相对路径不从根节点开始,而是从当前节点开始,描述了从当前节点到目标节点的路径。它以双斜杠(//)开头,例如://input[@id='username']

XPath的常用语法:

  1. 节点名称: 使用节点名称来定位元素,例如://input

  2. 属性定位: 使用节点的属性来定位元素,例如://input[@id='username']

  3. 索引定位: 使用索引号来定位元素,例如://div[1]/input[2]

  4. 逻辑运算符: 使用逻辑运算符(and、or)来组合多个条件,例如://input[@id='username' and @name='user']

  5. 文本内容: 使用元素的文本内容来定位元素,例如://a[text()='Next']

  6. 模糊匹配: 使用contains()函数进行模糊匹配,例如://input[contains(@class, 'form-control')]

  7. 父子关系: 使用斜杠(/)表示父子关系,例如://div[@id='parent']/input[@name='child']

下面是一个示例,演示如何使用XPath来定位一个元素:

假设我们有以下HTML代码:

<html><body><div id="container"><input type="text" id="username" name="username" placeholder="请输入用户名"><input type="password" id="password" name="password" placeholder="请输入密码"><button type="submit">登录</button></div></body>
</html>

我们可以使用XPath来定位用户名输入框,其XPath表达式为://input[@id='username']

然后,我们可以使用Selenium的find_element_by_xpath()方法来定位该元素:

element = driver.find_element_by_xpath("//input[@id='username']")

这样就能够成功定位到用户名输入框了。 

8、通过CSS选择器定位

        通过CSS选择器定位是Selenium中常用的一种定位方法,它利用元素的CSS属性来定位元素,具有灵活性和强大的定位能力。CSS选择器可以根据元素的标签名、类名、ID、属性等来定位元素,支持多种选择器语法,包括标签选择器、类选择器、ID选择器、属性选择器、层级选择器等。

使用find_element_by_css_selector()方法来通过CSS选择器定位元素,其基本语法如下:

element = driver.find_element_by_css_selector("css_selector")

其中,css_selector是要定位元素的CSS选择器。

通过CSS选择器定位的示例:

假设我们有以下HTML代码:

<div id="login_form" class="form-container"><input type="text" id="username" name="username" placeholder="请输入用户名"><input type="password" id="password" name="password" placeholder="请输入密码"><button type="submit" class="login-button">登录</button>
</div>

我们可以使用Selenium通过CSS选择器定位用户名输入框,其ID为username,示例代码如下:

username_input = driver.find_element_by_css_selector("#username")

我们也可以使用CSS选择器定位登录按钮,其类名为login-button,示例代码如下:

login_button = driver.find_element_by_css_selector(".login-button")

CSS选择器的常见语法:

  1. 标签选择器: 使用标签名定位元素,例如:divinput
  2. 类选择器: 使用类名定位元素,以点号.开头,例如:.login-button
  3. ID选择器: 使用ID定位元素,以井号#开头,例如:#username
  4. 属性选择器: 使用元素的属性来定位元素,例如:input[type='text']
  5. 层级选择器: 使用元素的层级关系来定位元素,例如:div.container input[type='text']

注意事项:

  1. CSS选择器定位可以使用多种选择器语法,根据需要选择合适的选择器。
  2. CSS选择器定位相比其他定位方法更加灵活,但在编写选择器时要确保选择器的准确性和唯一性,以避免定位到错误的元素。

9、定位一组元素

    在 Selenium 中,可以使用多种方法来定位一组元素。find_elements_by_xxx() 方法是Selenium中用于定位一组元素的方法之一,它与 find_element_by_xxx() 方法类似,但是返回的是一个元素列表,而不是单个元素。这意味着它可以定位页面上匹配给定条件的所有元素,而不仅仅是第一个匹配的元素。可以使用各种定位方法来定位一组元素,如通过ID、类名、标签名、XPath、CSS选择器等。

下面是一些常用的方法:

  • find_elements_by_xpath(xpath):通过 XPath 表达式定位一组元素。
  • find_elements_by_css_selector(selector):通过 CSS 选择器定位一组元素。
  • find_elements_by_id(id):通过元素的 id 属性定位一组元素。
  • find_elements_by_class_name(class_name):通过元素的 class 属性定位一组元素。
  • find_elements_by_tag_name(tag_name):通过元素的标签名定位一组元素。
  • find_elements_by_name(name):通过元素的 name 属性定位一组元素。
  • find_elements_by_link_text(link_text):通过链接文本定位一组链接元素。
  • find_elements_by_partial_link_text(partial_link_text):通过部分链接文本定位一组链接元素。

一旦找到了一组元素,可以对其进行遍历,或者使用索引来访问特定的元素。例如:

for element in elements:# 对每个元素执行操作pass# 访问第一个元素
first_element = elements[0]# 访问最后一个元素
last_element = elements[-1]

五、模拟用户操作

        当使用 Selenium 模拟用户操作时,主要目标是使自动化测试尽可能地模拟真实用户的行为。这包括点击按钮、填写表单、上传文件等常见的操作。下面是一些常见用户操作的示例以及如何使用 Selenium 进行模拟:

1、点击按钮

使用 click() 方法来模拟点击按钮。

button = driver.find_element_by_id("button_id")
button.click()

2、填写表单

使用 send_keys() 方法来填写表单字段。

input_field = driver.find_element_by_id("input_field_id")
input_field.send_keys("Input value")

3、上传文件

使用 send_keys() 方法来模拟文件上传操作。

file_input = driver.find_element_by_id("file_input_id")
file_input.send_keys("/path/to/file")

这里,/path/to/file 是想要上传的文件的路径。

4、下拉框选择

对于下拉框(select),可以使用 Select 类来模拟选择操作。

from selenium.webdriver.support.ui import Selectselect_element = driver.find_element_by_id("select_id")
select = Select(select_element)
select.select_by_visible_text("Option text")

这里的 "Option text" 是下拉框中选项的可见文本。

5、鼠标操作

在某些情况下,需要模拟鼠标操作,比如悬停或双击。可以使用 ActionChains 类来实现这些操作。

from selenium.webdriver.common.action_chains import ActionChainselement_to_hover_over = driver.find_element_by_id("element_id")
ActionChains(driver).move_to_element(element_to_hover_over).perform()

这个例子演示了如何悬停在一个元素上。

六、处理动态内容

        处理动态内容是 UI 自动化测试中至关重要的一部分,特别是当页面通过 JavaScript 动态加载内容时。在 Selenium 中,你可以使用不同的等待机制来处理这些情况,确保测试脚本在正确的时机执行操作。

1、等待页面加载完成

        有时页面上的某些元素可能需要一段时间才能加载完成。在这种情况下,你可以使用隐式等待或显式等待来等待页面加载完成。

(1)隐式等待:

driver.implicitly_wait(10) # 等待最多10秒钟

这将使 WebDriver 在查找元素时等待一段时间,直到元素出现或超时为止。

(2)显式等待:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECelement = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "element_id"))
)

这个例子将等待最多10秒钟,直到页面上具有指定 ID 的元素出现。

(3)处理元素可见:

有时元素虽然存在于 DOM 中,但可能不可见或不可交互。在这种情况下,你可以等待元素可见或可交互,然后执行相应的操作。

等待元素可见
element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "element_id"))
)

这个例子将等待最多10秒钟,直到页面上具有指定 ID 的元素可见。

等待元素可交互
element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "element_id"))
)

这个例子将等待最多10秒钟,直到页面上具有指定 ID 的元素可交互(即可被点击)。

处理异步加载内容

        有时页面上的内容是通过异步加载的,例如通过 AJAX 请求。在这种情况下,你需要等待特定的条件来确保内容已经加载完成。

element = WebDriverWait(driver, 10).until(lambda driver: driver.execute_script("return jQuery.active == 0")
)

这个例子将等待最多10秒钟,直到页面上没有活动的 jQuery AJAX 请求。

七、数据驱动测试

        数据驱动测试是一种测试方法,其中测试用例的输入数据和预期结果从外部数据源加载,而不是硬编码在测试脚本中。这种方法使得测试更灵活、可维护性更高,因为可以轻松地修改输入数据或添加新的测试用例,而无需修改测试脚本本身。

1、使用外部数据源驱动测试用例

        在这种方法中,通常会将测试数据存储在外部文件中,如 Excel、CSV 文件或数据库。然后,测试脚本会读取这些文件中的数据,并将其用于执行测试用例。

假设我们有一个 CSV 文件 testdata.csv,其中包含测试数据,格式如下:

username,password
user1,password1
user2,password2

我们可以使用 Python 的 csv 模块来读取这个文件,并在测试中使用其中的数据。

import csv# 读取 CSV 文件
with open('testdata.csv', 'r') as file:reader = csv.DictReader(file)for row in reader:username = row['username']password = row['password']# 在这里执行测试用例,使用 username 和 password 变量作为输入数据

假设我们有一个 Excel 文件 testdata.xlsx,其中包含测试数据,格式如下:

| username | password  |
|----------|-----------|
| user1    | password1 |
| user2    | password2 |

我们可以使用 Python 的 openpyxlxlrd 等库来读取这个 Excel 文件,并在测试中使用其中的数据。

import openpyxl# 读取 Excel 文件
workbook = openpyxl.load_workbook('testdata.xlsx')
sheet = workbook.active
for row in sheet.iter_rows(min_row=2, values_only=True):username = row[0]password = row[1]# 在这里执行测试用例,使用 username 和 password 变量作为输入数据

2、动态地生成测试数据

        有时候,测试需要使用动态生成的测试数据。Python 提供了许多库来生成测试数据,如 Fakerfakermimesis 等。

使用 Faker 库生成测试数据示例:

from faker import Fakerfake = Faker()# 生成随机的用户名和密码
username = fake.user_name()
password = fake.password()
# 在这里执行测试用例,使用生成的 username 和 password 变量作为输入数据

这样,我们就可以通过外部数据源或动态生成的方式来驱动测试用例,使得测试更加灵活和可维护。

八、测试报告

        生成详细的测试报告对于分析测试结果、发现问题并改进测试流程至关重要。在 Python Selenium 中,可以使用各种测试报告生成工具来生成报告,例如 unittestpytestHTMLTestRunner 等。下面是如何使用 pytestpytest-html 来生成详细的测试报告的示例:

1、安装 pytest 和 pytest-html

pip install pytest pytest-html

关于Pytest的使用,可以参考:

Pytest自动化测试框架详解 

2、编写测试用例

编写测试用例并使用 pytest 的装饰器 @pytest.mark.parametrize 来传递测试数据。

import pytest
from selenium import webdriver@pytest.mark.parametrize("username, password", [("user1", "password1"), ("user2", "password2")])
def test_login(username, password):driver = webdriver.Chrome()driver.get("http://example.com/login")driver.find_element_by_id("username").send_keys(username)driver.find_element_by_id("password").send_keys(password)driver.find_element_by_id("login_button").click()assert "Welcome" in driver.titledriver.quit()

3、运行测试并生成报告

使用 pytest 命令运行测试,并使用 --html 选项生成 HTML 格式的测试报告。

pytest --html=report.html

        这将生成一个名为 report.html 的测试报告文件,其中包含了测试的详细结果、测试用例的执行情况、失败的断言等信息。

九、实践和技巧

        当进行 Python Selenium UI 自动化测试时,有一些最佳实践和技巧可以帮助你编写更加稳健、可维护和可扩展的测试脚本。下面是一些常见的实用技巧:

1、隐式等待和显式等待

隐式等待(Implicit Waits): 设置一个全局的等待时间,使得 WebDriver 在查找元素时等待一段时间,直到元素出现或超时为止。

driver.implicitly_wait(10) # 等待最多10秒钟

显式等待(Explicit Waits): 显式等待允许在特定条件下等待元素的出现、可见性、可点击等,可以使测试更加精确和稳健。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECelement = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "element_id"))
)

2、页面对象模型(Page Object Model,POM)

        使用页面对象模型将页面的元素和操作封装到单独的页面对象类中,使测试脚本更加模块化、可读性更高,降低了测试维护的难度。

class LoginPage:def __init__(self, driver):self.driver = driverdef login(self, username, password):self.driver.find_element_by_id("username").send_keys(username)self.driver.find_element_by_id("password").send_keys(password)self.driver.find_element_by_id("login_button").click()
# 在测试用例中使用页面对象
login_page = LoginPage(driver)
login_page.login("user1", "password1")

3、使用 CSS 选择器优于 XPath

        尽可能使用 CSS 选择器而不是 XPath,因为 CSS 选择器通常比 XPath 执行更快,更简洁,并且更易于阅读和维护。

十、Selenium的常用函数或者方法

        Selenium 提供了丰富的函数和方法,用于模拟用户与网页的交互,定位元素,执行操作等。下面是一些 Selenium 中常用的函数和方法:

1、元素定位

  • find_element(by='id', value=None):根据指定的定位方式和值找到页面上的单个元素。
  • find_elements(by='id', value=None):根据指定的定位方式和值找到页面上的一组元素。
  • find_element_by_id(id):根据元素的 id 属性找到元素。
  • find_element_by_name(name):根据元素的 name 属性找到元素。
  • find_element_by_xpath(xpath):根据 XPath 表达式找到元素。
  • find_element_by_css_selector(css_selector):根据 CSS 选择器找到元素。
  • find_element_by_class_name(class_name):根据元素的 class 属性找到元素。
  • find_element_by_tag_name(tag_name):根据元素的标签名找到元素。

2、元素操作

  • click():点击元素。
  • send_keys(*value):在输入框中输入文本。
  • clear():清除输入框中的文本。
  • submit():提交表单。
  • get_attribute(name):获取元素的属性值。
  • is_displayed():判断元素是否可见。
  • is_enabled():判断元素是否可用(即是否可以与用户交互)。

3、等待

  • implicitly_wait(time_to_wait):设置隐式等待时间,全局性地等待一定时间直到元素出现。
  • WebDriverWait(driver, timeout).until(EC.condition()):显式等待,直到指定条件满足或超时。
  • expected_conditions 模块提供了多种等待条件,如元素可见、元素存在、元素可点击等。

4、浏览器操作

  • get(url):打开指定的 URL。
  • back():返回上一个页面。
  • forward():前进到下一个页面。
  • refresh():刷新当前页面。
  • close():关闭当前窗口。
  • quit():退出整个浏览器。

十一、示例

        下面是一个简单的示例,演示了如何使用 Python 和 Selenium 进行基本的网页自动化测试。在这个示例中,我们将访问一个测试页面,输入用户名和密码,然后点击登录按钮进行登录,最后验证登录是否成功。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC# 启动 Chrome 浏览器
driver = webdriver.Chrome()# 打开测试页面
driver.get("http://example.com/login")# 找到用户名和密码输入框,并输入用户名和密码
username_input = driver.find_element_by_id("username")
username_input.send_keys("test_user")password_input = driver.find_element_by_id("password")
password_input.send_keys("test_password")# 点击登录按钮
login_button = driver.find_element_by_id("login_button")
login_button.click()# 等待页面跳转,验证登录是否成功
try:# 等待页面标题包含 "Welcome"WebDriverWait(driver, 10).until(EC.title_contains("Welcome"))print("Login successful!")
except Exception as e:print("Login failed:", e)# 关闭浏览器
driver.quit()

        在这个示例中,我们使用了 Selenium 提供的 webdriver.Chrome() 方法来启动 Chrome 浏览器。然后,使用 driver.get() 方法打开测试页面。接着,我们找到用户名和密码输入框,分别输入用户名和密码。然后,通过 find_element_by_id() 方法找到登录按钮,并通过 click() 方法点击登录按钮。最后,我们使用显式等待来等待页面跳转,验证登录是否成功。

        我们添加了一个断言,验证页面标题是否包含 "Welcome"。如果页面标题包含 "Welcome",则认为登录成功,否则认为登录失败。如果断言失败,将会打印相应的错误消息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/19165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django学习

1.pycharm社区版创建django PyCharm社区版如何创建Django项目并运行_pycharm社区版打开django-CSDN博客 2.Django TemplateDoesNotExist: rest_framework 当我们使用djangorestframework框架时&#xff0c;首先下载pip install djangorestframework 参考博文Django Templat…

MATLAB分类与判别模型算法: 快速近邻法(FastNN)分类程序【含Matlab源码 MX_005期】

算法思路介绍&#xff1a; 1. 数据准备阶段&#xff1a; 生成一个合成数据集 X&#xff0c;其中包含三个簇&#xff0c;每个簇分布在不同的区域。 定义聚类层数 L 和每个层次的子集数量 l。 2. 聚类阶段&#xff1a; 使用K均值聚类算法将初始数据集 X 分成 l 个簇。…

Marin说PCB之如何在主板上补偿链路中的走线的等长误差?

一场雨把我困在这里&#xff0c;你冷漠地看我没有穿雨衣淋成落汤鸡。今天刚刚出门时候看天气预报没有雨&#xff0c;于是我就没有带雨衣骑电动车去公司了&#xff0c;谁知道回来的路上被淋成狗了。天气预报就像是女人的脾气那样&#xff0c;不能完全相信的。 好了&#xff0c;我…

编译安装MySQL服务(LAMP2)

目录 1.初始化设置&#xff0c;将安装mysql 所需软件包传到/opt目录下 &#xff08;1&#xff09;关闭防火墙 &#xff08;2&#xff09;上传软件包到/opt目录 2.安装环境依赖包 3.配置软件模块 4.编译及安装 5.创建mysql用户 6.修改mysql 配置文件 7.更改mysql安装目…

JavaScript-JavaWeb

目录 什么是JavaScript? js引入方式 js基础语法 书写语法 变量 数据据类型 运算符 类型转换 流程语句 js函数 js对象 1.Array 2.String 3.JSON js事件监听 什么是JavaScript? ● JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言。是用来控制网页行为的,它能…

2024了,还有人在问为甚死锁?

大家好&#xff0c;我是javapub。 接上篇提到了锁&#xff0c;《InnoDB有哪些锁类型》。这么多的锁&#xff0c;你有遇到过死锁吗&#xff1f; 死锁是在事务数据库中会发生的一种特殊现象&#xff0c;多个事务在执行过程中&#xff0c;相互等待对方持有的资源&#xff0c;导致…

Docker-一文详解容器通信的基础网络模式及衍生的自定义网络模式

启动容器时&#xff0c;通过-p 宿主机端口:容器端口&#xff0c;就可以通过访问宿主机端口访问到容器&#xff0c;这种原理机制是啥&#xff0c;有没有其它方式可以让宿主机和容器通信&#xff0c;以及容器与容器之间如何通信。带着这几个问题开始学习Docker的网络知识。 文章…

【Linux】初识Linux和Linux环境配置

1.什么是Linux操作系统 说到电脑系统 我想有大多数人会脱口而出&#xff1a;windows、mac 是的&#xff0c;这也是如今市场上主流的两种操作系统。 但是对于IT相关的人士来说&#xff0c;还有一种系统也是必须有姓名 那就是Linux Linux&#xff0c;Linux Is Not UniX 的…

PV PVC

默写 1 如何将pod创建在指定的Node节点上 node亲和、pod亲和、pod反亲和: 调度策略 匹配标签 操作符 nodeAffinity 主机 In,NotIn,Exists,DoesNotExist&#xff0c;Gt&#xff0c;Lt podAffinity …

代码随想录-Day23

669. 修剪二叉搜索树 方法一&#xff1a;递归 class Solution {public TreeNode trimBST(TreeNode root, int low, int high) {if (root null) {return null;}if (root.val < low) {return trimBST(root.right, low, high);} else if (root.val > high) {return trimBS…

C语言:从键盘输入若干行字符(每行长度不等),输入后把它们存储到一磁盘文件中。再从该文件中读入这些数据,将其中小写字母转换成大写字母后在显示屏上输出。

void load(char str[100]) {int i 0;FILE* pf fopen("count.txt", "r");if (pf NULL){perror("error:");return 1;}printf("把字符转成大写后\n");while (fscanf(pf,"%s",str)!EOF){for (i 0; str[i] ! \0; i){if (str[…

24V_2A_1.2MHZ|PCD0303升压恒频LCD背光源专用电路超小体积封装

概述 PCD0303是一个恒定频率&#xff0c;6针SOT23电流模式升压转换器用于小型低功耗应用。PCD0303 以1.2MHz切换&#xff0c;并且允许使用微小的&#xff0c;低成本电容器和电感器2mm或更小,内部软启动会产生较小的涌入电流延长电池寿命。PCD0303具有自动切换至轻负载下的脉冲…

磁带存储:“不老的传说”依然在继续

现在是一个数据指数增长的时代&#xff0c;根据IDC数据预测&#xff0c;2025年全世界将产生175ZB的数据。 这里面大部分数据是不需要存储的&#xff0c;在2025预计每年需要存储11ZB的数据。换算个容易理解的说法&#xff0c;1ZB是10^18Bytes, 相当于要写5556万块容量18TB的硬盘…

探数API分享-全球电价一览:谁最高,谁最低?

全球家庭用电价格的平均水平约为0.139美元/千瓦时&#xff0c;这是根据2021年12月的统计数据得出的。在这个平均水平之上&#xff0c;有一些国家的家庭用电价格远超过这个数值&#xff0c;特别是在欧洲的一些发达国家。 丹麦、荷兰、德国、英国、西班牙、比利时等国家的家庭用…

6.S081的Lab学习——Lab5: xv6 lazy page allocation

文章目录 前言一、Eliminate allocation from sbrk() (easy)解析&#xff1a; 二、Lazy allocation (moderate)解析&#xff1a; 三、Lazytests and Usertests (moderate)解析&#xff1a; 总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。打算尝试6.S081&#xff0…

快手自动私信获客软件,精准定位潜在客户

在当今数字化营销时代&#xff0c;短视频平台已成为企业与个人品牌不可忽视的流量宝地。快手作为国内领先的短视频社交平台&#xff0c;汇聚了庞大的用户群体和丰富的兴趣社区&#xff0c;为各类商家、创作者提供了无限商机。如何在快手平台上高效引流获客&#xff0c;实现精准…

JAVA-->方法的使用详解

JAVA–>方法的使用详解 1.方法的概念及使用 1.1 什么是方法 : 方法就是一个代码片段. 类似于 C 语言中的 “函数”。 1.2 方法定义 / 方法定义 修饰符 返回值类型 方法名称([参数类型 形参 ...]){方法体代码;[return 返回值]; }判断是否为闰年 public class Method{ //…

JDBC使用步骤-小白入门

一.JDBC开发流程 加载并注册JDBC驱动创建数据库连接创建Statement对象遍历查询结果关闭连接,释放资源 import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement;public class StandardJDBCSample {public static …

opencv进阶 ——(七)图像处理之寸照换背景

寸照换背景&#xff0c;通常指的是将个人证件照片的背景色更换为另一种颜色&#xff0c;如白色、蓝色或红色等&#xff0c;以满足不同用途的要求。例如&#xff0c;护照照片通常要求白色背景&#xff0c;而身份证照片可能需要蓝色背景。这个过程通常涉及到图像处理技术&#xf…

【国产中颖】SH79F9202U单片机驱动LCD段码液晶学习笔记

1. 引言 因新公司之前液晶数显表产品单片机一直用的是 C51单片机(SH79F9202U9)&#xff0c;本人之前没有接触过这款单片机&#xff0c;为了维护老产品不得不重新研究研究这款单片机。 10位ADC LCD的增强型8051微控制器 SH79F9202是一种高速高效率8051可兼容单片机。在同样振…