python+selenium工具UI自动化全功能介绍(包括工具本身及配合RobotFramework框架和pytest框架应用)

文章较长,各位志同道合的朋友们,感谢关注收藏。

书山有路勤为径,学海无涯苦作舟。 ------韩愈,以山川学海比喻学习的艰辛与努力的方向。

明天的我们,必将会感谢昨日的自己。

1 UI自动化测试

UI自动化测试(User Interface Automation Testing)是一种通过编写脚本或使用自动化测试工具,对界面(UI)进行自动化测试的方法。原理主要是模拟用户打开客户端或网页的UI界面,自动化执行用户界面上的操作,如点击按钮、输入文本、选择但下拉框/单选,多选项等,并检查测试对象的响应行为是否符合预期。

比如一些常用的测试框架或者工具(robotframework,testng,pytest,selenium,appnium,playwright等)都支持UI界面的自动化测试,而这节内容主要介绍下pytest框架+selenium工具在web端的自动化实践。

2 selenium安装

使用pip命令安装: pip install selenium -i https://mirrors.aliyun.com/pypi/simple/

下载的是最新版本4.23.1,需要适配python版本3.8+。

selenium安装后目录结构如下:

3 selenium介绍

Selenium是一个用于Web应用程序的自动化测试工具,支持多平台(Windows、Linux和Mac)、多浏览器(IE,Mozilla Firefox、Safari、Google Chrome、Opera、Edge)、多语言(Java、Python、C#、JavaScript、Ruby),能够让测试脚本像真实用户一样在浏览器中操作。

核心组件:

Selenium IDE:Selenium Suite下的开源Web自动化测试工具,是Firefox的一个插件,具有记录和回放功能,无需编程即可创建测试用例。

Selenium WebDriver:Selenium 2.0及以后版本的核心,通过原生浏览器支持或浏览器扩展直接控制浏览器,取代了Selenium RC中的JavaScript注入技术。

Selenium Grid:一种自动化测试辅助工具,能够加快Web应用的功能测试,支持并行执行多个测试事例。

3.1 MAC系统-配置selenium控制safari浏览器

safari浏览器从10及以上版本通常内置了对WebDriver的支持

不需要下载下载浏览器的驱动,但是需要配置浏览器支持使用selenium打开。如果不配置执行程序会报以下错误:

1)配置步骤:

  1. 打开Safari浏览器。

  2. 点击菜单栏上的"Safari浏览器",然后选择"偏好设置"(Preferences)。

  3. 在偏好设置窗口中,点击"高级"(Advanced)标签页。

  4. 勾选"在菜单栏中显示'开发'菜单"(Show Develop menu in menu bar)。

  5. 关闭偏好设置窗口,然后点击菜单栏上的"开发"(Develop)菜单。

  6. 勾选"允许远程自动化"(Allow Remote Automation)。

2)配置后我们使用selenium打开safari浏览器

首先导入selenium.webdriver,然后我们打开浏览器,等待一段时间后使用quit函数退出浏览器。

from selenium import webdriver
import time
# 创建Safari浏览器的WebDriver实例
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
#打开后等待60s退出
time.sleep(60)
# 关闭浏览器
driver.quit()

python程序执行后,结果如下:会自动打开浏览器输入百度网址,完成访问。

3.2 MAC系统-配置selenium控制google的chrome浏览器

google浏览器不像safari浏览器,使用前我们先要下载驱动程序(下载地址https://chromedriver.storage.googleapis.com/index.html),驱动程序的版本要跟浏览器的版本一致,比如浏览器是127版本,驱动程序也要下载127的版本(目前还没有127的版本驱动,大家可以降低浏览器的版本再下载对应)。

下载网址打开后,选择对应的版本,然后选择支持windows系统的包

下载后解压,并将程序chromedriver放到/usr/local/bin目录下,并执行命令赋予权限:sudo xattr -d com.apple.quarantine chromedriver。否则无权限通过selenium打开后会报如下错误:

2)配置后我们使用selenium打开google浏览器

首先导入selenium.webdriver,然后我们打开浏览器,等待一段时间后使用quit函数退出浏览器。

from selenium import webdriver
from time import sleep
# 创建浏览器WebDriver实例
driver = webdriver.Chrome()
# 打开一个网页
driver.get("https://www.baidu.com")
# 等待几秒钟以便观察浏览器行为
sleep(60)
# 关闭浏览器
driver.quit()

3.3 windows系统-配置selenium控制google的chrome浏览器

跟配置MAC系统一样,使用前我们先要下载驱动程序(下载地址https://chromedriver.storage.googleapis.com/index.html),驱动程序的版本要跟浏览器的版本一致,比如浏览器是127版本,驱动程序也要下载127的版本。

下载网址打开后,选择对应的版本,然后选择支持windows系统的包(目前还没有127的版本驱动,大家可以降低浏览器的版本再下载对应)。

下载网址打开后,选择对应的版本,然后选择支持windows系统的包,

下载后解压,并将程序chromedriver放到python的安装目录下,比如'D:/Python3'.

2)配置后我们使用selenium打开google浏览器

首先导入selenium.webdriver,然后我们打开浏览器,等待一段时间后使用quit函数退出浏览器。

from selenium import webdriver
from time import sleep
# 创建浏览器WebDriver实例
driver = webdriver.Chrome()
# 打开一个网页
driver.get("https://www.baidu.com")
# 等待几秒钟以便观察浏览器行为
sleep(60)
# 关闭浏览器
driver.quit()

4 selenium的webdriver介绍

从selenium导入webdriver模块,在pycharm中跳转webdriver模块的__init__.py文件,内容如图所示:从selenium包的子目录中导入了很多模块并做了重命名,用于支持如下Chrome/Edge/Ie/Firefox/Safari浏览器。

使用方法类似如下:

先导入webdriver模块

from selenium import webdriver

初始化各个浏览器的webdriver类:

driver = webdriver.Chrome()
driver = webdriver.Edge()
driver = webdriver.Firefox()
driver = webdriver.Ie()
driver = webdriver.Safari()

然后使用get函数打开网页地址,比如打开百度

driver.get("https://www.baidu.com/")

4.1 web页面元素的查找方法

当打开网页后我们得先定位到网页中各个元素的位置和信息,这样selenium才能做对应的操作。

举例:打开百度网页后,通过查找元素,找到输入框和百度一下对应元素信息。

1)输入框的元素信息:<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">

复制Xpath地址为://*[@id="kw"]

2)百度一下按钮的元素信息:

<input type="submit" id="su" value="百度一下" class="bg s_btn">

对应Xpath为://*[@id="su"]

3)通过以上元素信息我们就拿到了输入框和百度一下按钮的id信息,然后获取后输入文本和点击按钮,就完成了一次查找和点击的动作。

当然我们除了通过id获取元素,也可以通过name,xpath等方式操作,大家不妨多试下,此处不再赘述。

4.2 webdriver.WebDriver类中的常用方法

在webdriver模块中WebDriver类提供了很多方法,比如我们最常用的find_element方法用于找元素,get方法用于打开网页等,具体介绍如下:

|---------------------------------|---------------------------------------------------------|--------------------------------------------------------------|
| 类型 | 函数 | 作用 |
| 网页相关 | get() | 打开传入的URL网页地址 |
| 网页相关 | current_url | 是一个属性方法,返回当前url |
| 网页相关 | page_source | 是一个属性方法,返回当前打开页面的源代码 |
| 网页相关 | refresh() | 刷新当前页面。 |
| 网页相关 | back() forward() | 浏览器的后退和前进操作。 |
| 网页相关 | implicitly_wait() | 是一种智能等待,指在设置的等待时间范围内,只要满足了执行条件,就会立即结束等待,继续往下进行,如果超时,则抛出异常。 |
| 网页相关 | set_script_timeout(seconds) | 设置脚本执行的时间,指在设置的等待时间范围内,只要满足了执行条件,就会立即结束等待,继续往下进行,如果超时,则抛出异常。 |
| 网页相关 | set_page_load_timeout(seconds) | 设置页面加载的时间,指在设置的等待时间范围内,只要满足了执行条件,就会立即结束等待,继续往下进行,如果超时,则抛出异常。 |
| 网页相关 | timeouts | 属性方法,返回包含上面三个时间的Timeouts对象,并可以设置三个时间的值。 |
| cookies操作 | get_cookies() | 获取页面对应的cookie列表 |
| cookies操作 | get_cookie(name) | 获取cookie列表中其中一个name=传入值的cookie,获取不到返回None |
| cookies操作 | delete_cookie(name) | 删除cookie列表中其中一个name=传入值的cookie |
| cookies操作 | delete_all_cookies() | 删除所有的cookie |
| cookies操作 | add_cookie(cookie_dict) | 添加一个cookie字典 |
| 窗口操作 | maximize_window() minimize_window() fullscreen_window() | 最大化或最小化或者全屏浏览器窗口。 |
| 窗口操作 | window_handles() | 存放打开窗口的句柄,用于切换不同窗口 |
| 窗口操作 | current_window_handle() | 返回当前窗口的句柄 |
| 窗口操作 | switch_to.window() | 切换不同的窗口页面(参数传入window_handles() 返回的列表中的某个句柄) |
| 窗口操作 | get_window_rect() | 获取窗口的坐标和大小 |
| 窗口操作 | set_window_rect() | 设置窗口的坐标和大小(坐标指距离屏幕左上角的横坐标和竖坐标值) |
| 窗口操作 | get_window_position() | 获取窗口的坐标,默认是当前窗口,也可以传某个窗口句柄(坐标指距离屏幕左上角的横坐标和竖坐标值) |
| 窗口操作 | set_window_position() | 设置窗口的坐标,默认是当前窗口,也可以传某个窗口句柄 |
| 窗口操作 | get_window_size() | 获取窗口的大小,默认是当前窗口,也可以传某个窗口句柄 |
| 窗口操作 | set_window_size() | 窗口的大小,默认是当前窗口,也可以传某个窗口句柄 |
| 窗口操作 | close() | 关闭当前窗口 |
| SwitchTo类对应的一些操作: 提示框操作 frame操作 | switch_to.alert() | 切换到提示框对象 |
| SwitchTo类对应的一些操作: 提示框操作 frame操作 | switch_to.frame() | 切换到不同的frame |
| SwitchTo类对应的一些操作: 提示框操作 frame操作 | switch_to.default_content() | 退出到默认frame |
| SwitchTo类对应的一些操作: 提示框操作 frame操作 | switch_to.parent_frame() | 退出到上一级frame |
| 执行js脚本 | execute_script() | 执行js脚本 |
| 执行js脚本 | execute_async_script() | 异步的执行js脚本 |
| 退出操作 | quit() | 关闭所有窗口,退出浏览器 |

selenium中查找元素方法

初始化好某浏览器的webdriver后,使用get函数打开网页地址,然后使用find_element(返回元素对象WebElement)或者find_elements方法(返回元素对象WebElement的列表)查找页面元素对象,有了元素对象,才能做接下来的一些操作,比如输入文本/点击按钮等。

,函数源代码如下:适用selenium4.23.1版本

函数中的参数by表示定位元素的方式,在

selenium.webdriver.common.by.By中定义如下:

函数中的参数value表示参数by对应的值。

也就是说find_element函数可以通过以下8种方式进行元素定位:

["id", "xpath", "link text", "partial link text", "name", "tag name", "class name", "css selector"]

举例:使用Safari浏览器打开百度,以id来定位搜索框的元素位置。

from selenium import webdriver
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
driver.find_element(By.ID,'kw')

举例:使用Safari浏览器打开百度,以name来定位搜索框的元素位置。

driver.find_element(By.NAME,'wd')

举例:使用Safari浏览器打开百度,以class来定位搜索框的元素位置。

driver.find_element(By.CLASS_NAME,'s_ipt')

举例:使用Safari浏览器打开百度,以Xpath来定位搜索框的元素位置。

driver.find_element(By.XPATH,'//*[@id="kw"]')

举例:使用Safari浏览器打开百度,以link text来定位新闻链接的元素位置。

driver.find_element(By.LINK_TEXT,'新闻')

设置隐式等待时间implicitly_wait

测试代码:

from selenium import webdriver
driver = webdriver.Safari()
driver.implicitly_wait(5)

设置脚本等待时间set_script_timeout

测试代码:

from selenium import webdriver
driver = webdriver.Safari()
driver.set_script_timeout(5)

设置页面加载等待时间set_page_load_timeout

测试代码:

from selenium import webdriver
driver = webdriver.Safari()
driver.set_page_load_timeout(5)

获取所有设置的等待或者超时时间timeouts

timeouts属性函数返回的是Timeouts类,包含三个属性

测试代码:

1)设置等待和超时时间后,通过timeouts属性函数读取这些设置的时间

from selenium import webdriver
driver = webdriver.Safari()
driver.implicitly_wait(5)
driver.set_script_timeout(5)
driver.set_page_load_timeout(5)
print(driver.timeouts.implicit_wait)
print(driver.timeouts.page_load)
print(driver.timeouts.script)

执行结果:

5.0

5.0

5.0

2) 设置timuouts属性中三个时间

先导入Timeouts类

from selenium.webdriver.common.timeouts import Timeouts

测试代码:

from selenium import webdriver
#初始化Timeouts类 并设置时间
timeouts_new = Timeouts()
timeouts_new.implicit_wait = 4
timeouts_new.page_load = 4
timeouts_new.script = 4
#将属性timeouts设置为Timeouts对象
driver.timeouts = timeouts_new
#打印3个时间值
print(driver.timeouts.implicit_wait)
print(driver.timeouts.page_load)
print(driver.timeouts.script)

执行结果:

4.0

4.0

4.0

网页的一些操作方法

先定义Safari浏览器的driver对象

from selenium import webdriver
driver = webdriver.Safari()
  • 返回当前url

    print(driver.current_url)

  • page_source 是一个属性方法,返回当前打开页面的源代码

    print(driver.page_source)

  • refresh() 刷新当前页面。

    driver.refresh()

  • back()和forward() 浏览器的后退和前进操作。

    driver.back()
    driver.forward()

  • 退出webdriver

    driver.quit()

cookie操作方法

from selenium import webdriver
  • 获取所有cookie

    print(driver.get_cookies())

  • 获取某个name值的cookie

    print(driver.get_cookie('__ac_nonce'))

  • 删除某个name值的cookie

    driver.delete_cookie('__ac_nonce')

  • 删除所有cookie

    driver.delete_all_cookies()

  • 添加一个cookie

    driver.add_cookie({'name':'nonce', 'value': '7421004976065267240'})

窗口操作方法

from selenium import webdriver
  • 获取窗口大小并设置窗口大小
#获取窗口大小
print(driver.get_window_size())
#设置大小
driver.set_window_size(1000,600)
print(driver.get_window_size())
  • 获取窗口坐标并设置窗口坐标
#获取坐标
print(driver.get_window_position())
#设置坐标
driver.set_window_position(20,30)
print(driver.get_window_position())
  • 获取窗口坐标和大小并设置窗口坐标和大小
#获取坐标和大小
print(driver.get_window_rect())
#设置坐标和大小
driver.set_window_rect(20,30,800,700)
print(driver.get_window_rect())
  • 窗口最大化/最小化/全屏
driver.minimize_window()
driver.maximize_window()
driver.fullscreen_window()
  • 关闭窗口

    driver.close()

  • 切换窗口

通过driver.window_handles获取打开窗口的句柄列表,然后通过driver.switch_to.window()切换不同的窗口

以百度网站举例,打开新闻链接,然后切换窗口

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(2)
#打开新闻链接
driver.find_element(By.LINK_TEXT,'新闻').click()
#打印文件句柄
print(driver.window_handles)
#循环切换窗口
while True:
  for i in driver.window_handles:
    sleep(1)
    driver.switch_to.window(i)

程序执行后,会打开新闻,然后来回切换两个窗口

当我们通过webdriver中的find_element函数定位到元素后,其实返回的是WebElement对象,而该对象有很多重要的方法,比如输入文本,点击按钮,获取属性,截屏等

5 WebElement类的方法介绍

常用方法

|-----------|-----------------------------|-------------------------------------------|
| 文本输入与清除 | send_keys() | 在元素上模拟按键输入,通常用于向输入框中填充文本。 |
| 文本输入与清除 | clear() | 清除元素的输入内容,如清空一个文本输入框。 |
| 点击操作 | click() | 单击元素,可以是按钮、链接等可点击的元素。 |
| 点击操作 | submit() | 提交表单,也可以使用click()方法,但submit()方法专门用于表单的提交。 |
| 元素属性与状态获取 | get_attribute(element_name) | 获取元素的属性值,如id、name、type等。 |
| 元素属性与状态获取 | is_selected() | 判断元素是否被选中,常用于单选框、复选框等。 |
| 元素属性与状态获取 | is_displayed() | 判断元素是否可见,返回一个布尔值。 |
| 元素属性与状态获取 | is_enabled() | 判断元素是否可启用,例如,某些按钮在特定条件下可能不可点击。 |
| 获取元素尺寸与位置 | size | 返回元素的尺寸,通常包含宽度和高度。 |
| 获取元素尺寸与位置 | location | 返回元素在页面上的位置,通常是元素的左上角坐标。 |
| 获取元素信息 | text | 获取元素的文本内容,如获取一个段落或链接的文本。 |
| 获取元素信息 | tag_name | 获取元素的tag信息。 |
| 截屏 | screenshot(filename) | 将当前元素截屏保存为png图片 |
| 截屏 | screenshot_as_base64 | 将当前元素截屏保存为base64编码的字符串 |
| 截屏 | screenshot_as_png | 将当前元素截屏保存为base64字符串,然后解码为2进制字节码 |

以上函数位于如下webelement.WebElement类中:

示例:打开百度输入文本后点击搜索(输入框操作)

我们以获取元素的id举例,先上代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
# 创建Safari浏览器的WebDriver实例
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
#最大化网页
driver.maximize_window()
#查找id=kw的元素位置,对应于搜索输入框,找到后我们输入字符python
driver.find_element(By.ID,'kw').send_keys('python')
##查找id=su的元素位置,对应于'百度一下'的按钮,找到后我们点击按钮
driver.find_element(By.ID,'su').click()
# 等待几秒
sleep(5)
# 关闭浏览器
driver.quit()

代码执行后,网页自动打开并搜索如下:

示例:打开百度输入用户名和密码进行登录(表单操作)

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(1)
#点击登录
driver.find_element(By.ID,'s-top-loginbtn').click()
sleep(1)
#输入用户名
driver.find_element(By.ID,'TANGRAM__PSP_11__userName').send_keys('*****')
sleep(1)
#输入密码
driver.find_element(By.ID,'TANGRAM__PSP_11__password').send_keys('*****')
sleep(1)
#点击同意
driver.find_element(By.ID,'TANGRAM__PSP_11__isAgree').click()
sleep(1)
#点击提交
driver.find_element(By.ID,'TANGRAM__PSP_11__submit').submit()

程序执行后会自动输入用户和密码,点击登录。

示例:获取元素后将元素截屏

我们获取元素后,使用函数screenshot将元素截屏,参数filename传入完整的png文件名路径或者文件名(放在当前路径)

测试代码:打开头条网站,定位到左上角的'下载头条app'然后截屏保存。

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
#打开传入的URL网页地址
driver.get("https://www.toutiao.com/")
sleep(6)
element = driver.find_element(By.XPATH,'//*[@id="root"]/div/div[3]/div[1]/div')
element.screenshot('1.png')
element.screenshot('/Users/aaa/Donwloads/1.png')

执行后打开截图如下:

示例:获取元素的text/ta gtag_name信息

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
#打开传入的URL网页地址
driver.get("https://www.toutiao.com/")

定位到左上角的'下载头条app'元素,并打印元素的信息

element = driver.find_element(By.XPATH,'//*[@id="root"]/div/div[3]/div[1]/div')
#打印该元素的一些信息
print(element.tag_name)
print(element.text)

执行结果:
DIV
下载头条APP扫码下载今日头条

示例:获取元素的属性值

通过get_attribute函数,传入参数比如id,class,xpath等信息,返回对应的值。

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
#打开传入的URL网页地址
driver.get("https://www.toutiao.com/")
#定位到左上角的'下载头条app'然后截屏保存。
element = driver.find_element(By.XPATH,'//*[@id="root"]/div/div[3]/div[1]/div')
#打印该元素的属性值
print(element.get_attribute('class'))

执行结果:

download-app-wrapper

6 Alert类用于操作提示框/确认弹框

之前文章我们提到,在webdriver.WebDriver类有一个switch_to方法,通过switch_to.alert()

可以返回Alert对象,而Alert对象主要用于网页中弹出的提示框/确认框/文本输入框的确认或者取消等动作。

Alert介绍

当在页面定位到提示框/确认框/文本录入框并点击后,页面会弹出对话框,通过driver.switch_to.alert切换到Alert对象。

Alert类主要提供四个方法:

  • accept(): 在弹出的对话框中点击确认

  • dismiss():在弹出的对话框中点击取消

  • send_keys(str):在弹出的对话框中录入文本

  • text:属性方法,获取对话框的text信息

示例:自定义一个html文件包括提示框/确认框/文本录入框

我们自定义一个html文件,包含一个提示框 确认框 文本输入框信息,html文件如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="javascript:alert('提示框')" id="alert" >提示</a><br>
<a href="javascript:confirm('确认删除吗?')" id="conform" >删除</a><br>
<a href="javascript:var content=prompt('请输入文本');document.write(content)" id="prompt" >录入</a><br>
<input type="submit" value="提交" id="su" class="btn self-btn bg s_btn">
</body>
</html>

html文件打开后如下,可以点击弹出提示框,确认框和文本输入框

示例:点击提示框,点击确认

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
# 打开一个网页
driver.get("file:///Users/htsc/Desktop/myhtml2.html")
driver.maximize_window()
sleep(2)
#定位到提示框并点击
driver.find_element(By.ID,'alert').click()
sleep(1)
#切换到提示框对象
alertins = driver.switch_to.alert
#点击确认
alertins.accept()
sleep(3)

点击删除,弹出确认框,可点击取消或者确认

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
# 打开一个网页
driver.get("file:///Users/htsc/Desktop/myhtml2.html")
driver.maximize_window()
sleep(2)
#定位到删除并点击
driver.find_element(By.ID,'confirm').click()
sleep(1)
#切换到确认框对象
alertins = driver.switch_to.alert
#点击确认或者点击取消
alertins.accept()
alertins.dismiss()
sleep(3)

点击录入,弹出文本输入框,输入文本后点击确认或者取消

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
# 打开一个网页
driver.get("file:///Users/htsc/Desktop/myhtml2.html")
driver.maximize_window()
sleep(2)
#定位到删除并点击
driver.find_element(By.ID,'prompt').click()
sleep(1)
#输入文本信息
alertins.send_keys('我爱中国')
sleep(1)
#切换到确认框对象
alertins = driver.switch_to.alert
#点击确认或者点击取消
alertins.accept()
alertins.dismiss()
sleep(3)

程序执行后,录入信息,截图如下:

7 selenium有多个frame页时的操作方法

之前文章我们提到,在webdriver.WebDriver类有一个switch_to方法,通过switch_to.frame()可以切换到不同的frame页然后才再定位某个元素做一些输入/点击等操作。

比如下面这个测试网站有2个frame页:

http://www.sahitest.com/demo/framesTest.htm,每个frame页的元素是一样的。

检查下Link Test的元素信息,发现两个frame,在每个frame下面都有这个元素的相同信息。

switch_to.frame方法

当我们定义好driver对象,打开网页并使用driver.switch_to.frame()方法切换frame时,该方法其实调用了selinium中的SwitchTo类中的frame方法:

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
# 打开一个网页
driver.get("http://www.sahitest.com/demo/framesTest.htm")

方法中的参数frame_reference可以是fame的name,或者代表frame的数字(从0开始),或者是该frame元素位置,如函数中的的介绍。

  • driver.switch_to.frame('frame_name')

  • driver.switch_to.frame(1)

  • driver.switch_to.frame(driver.find_elements(By.TAG_NAME, "iframe")[0])

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
# 打开一个网页
driver.get("http://www.sahitest.com/demo/framesTest.htm")
driver.maximize_window()
sleep(2)

#先切换到第1个frame
driver.switch_to.frame(0)
sleep(1)
#点击TestLink链接
driver.find_element(By.XPATH,'/html/body/table/tbody/tr/td[1]/a[1]').click()
sleep(2)

#完成后 先返回上一级frame或者默认frame 然后才能切换到第2个frame
#以下两个方法都可使用
driver.switch_to.default_content()
#driver.switch_to.parent_frame()

#切换第2个frame
driver.switch_to.frame(1)
sleep(1)
driver.find_element(By.XPATH,'/html/body/table/tbody/tr/td[1]/a[1]').click()
sleep(4)

8 ActionChains类模拟鼠标和键盘操作

selenium包中提供了ActionChains类,主要用于鼠标和键盘的一些操作,比如鼠标移动,鼠标按键,或者是悬停和拖放等;模拟键盘按键输入,比如按住control+C键等。

使用时先导入该类:

from selenium.webdriver import ActionChains

ActionChains类的方法

|-----------------------------|---------------------------------------------------------------------------------|
| 函数 | 功能 |
| move_to_element | 鼠标移动到某个元素位置 |
| move_to_element_with_offset | 鼠标移动到离某个元素距离多少的位置 |
| move_by_offset | 移动鼠标到某个坐标 |
| click | 单击鼠标左键 |
| click_and_hold | 单击鼠标左键不松开 |
| double_click | 双击鼠标左键 |
| context_click | 点击鼠标右键 |
| drag_and_drop | 拖拽到某个元素然后松开 |
| drag_and_drop_by_offset | 拖拽到某个坐标然后松开 |
| key_down | 按下某个键盘上的按键; 键盘输入通常用到如下Keys类中的属性 from selenium.webdriver.common.keys import Keys |
| key_up | 松开某个按键 |
| first_selected_option | 第一个选择的选项 |
| send_keys | 可发送多个键盘上的按键到当前焦点位置,循环的模拟输入按键和松开按键 ; 上面提到的send_keys模拟文本输入,功能有所不同。 |
| send_keys_to_element | 发送某个按键到某个元素 |
| pause | 暂停执行一段时间 |
| release | 在元素上释放按住的鼠标按钮 |
| reset_actions | 清除已经储存的上述方法中的动作 |
| perform | 执行已经存储的上述方法中的动作。想要执行上述方法,最后需要执行该函数来生效。 |

方法执行类似如下:移动鼠标到某个定位到的元素,然后右键点击,最后加上perform函数完成整个动作(actchain_ins为ActionChains类初始化的实例对象)。

actchain_ins.move_to_element(driver.find_element(By.ID,'su')).context_click().perform()

示例:打开百度网页,将鼠标定位到'更多'展示隐藏的内容

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(2)
#初始化ActionChains类
actchain_ins = webdriver.ActionChains(driver)
#移动到'更多'元素的位置
actchain_ins.move_to_element(driver.find_element(By.NAME,'tj_briicon')).perform()
actchain_ins.pause(5).perform()

执行后展示如图:

示例:打开百度输入用户名和密码进行登录(表单操作)

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(1)
#初始化ActionChains类
actchain_ins = webdriver.ActionChains(driver)
#模拟鼠标点击登录按钮
actchain_ins.move_to_element(driver.find_element(By.ID,'s-top-loginbtn')).click().perform()
sleep(1)
#输入用户名
driver.find_element(By.ID,'TANGRAM__PSP_11__userName').send_keys('*******')
sleep(1)
#输入密码
driver.find_element(By.ID,'TANGRAM__PSP_11__password').send_keys('*******')
sleep(1)
#模拟鼠标点击'阅读并接受'前面的选框
actchain_ins.move_to_element(driver.find_element(By.ID,'TANGRAM__PSP_11__isAgree')).click().perform()
sleep(1)
#模拟鼠标点击登录
actchain_ins.move_to_element(driver.find_element(By.ID,'TANGRAM__PSP_11__submit')).click().perform()
sleep(3)

程序执行后会自动输入用户和密码,点击登录,如下图:

示例:打开百度后在百度一下按钮处点击鼠标右键

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(2)
#ActionChains初始化
actchain_ins = webdriver.ActionChains(driver)
#在百度一下按钮处,点击右键
actchain_ins.move_to_element(driver.find_element(By.ID,'su')).context_click().perform()

示例:打开百度输入要搜索的内容后发送键盘键进行剪切和粘贴

键盘输入使用的是如下Keys类,使用前我们先导入

from selenium.webdriver.common.keys import Keys

Keys类有很多键盘的按键属性:

主要使用方法:通过key_down按下某个按键,通过send_keys发送某个按键,然后key_up松开某个按键。比如下面这个按住苹果电脑上的COMMAND+A键,然后再松开COMMAND键,完成全选动作。

actchain_ins.key_down(Keys.COMMAND).send_keys('A').key_up(Keys.COMMAND).perform()

测试代码如下:输入搜索内容后,全选文本后,剪切然后再粘贴。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from time import sleep
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(2)
#初始化
actchain_ins = webdriver.ActionChains(driver)
driver.find_element(By.ID,'kw').send_keys('python')
#control+A复制 苹果电脑是COMMAND键
actchain_ins.key_down(Keys.COMMAND).send_keys('A').key_up(Keys.COMMAND).perform()
sleep(1)
#control+X剪切
actchain_ins.key_down(Keys.COMMAND).send_keys('X').key_up(Keys.COMMAND).perform()
sleep(1)
#control+V粘贴
actchain_ins.key_down(Keys.COMMAND).send_keys('V').key_up(Keys.COMMAND).perform()
sleep(20)

执行后,录制的视频如下:

剪切粘贴

示例:使用ActionChains 类模拟鼠标滚轮操作

使用函数ActionChains.send_keys发送按键Keys.PAGE_DOWN往下滑动页面,发送按键Keys.PAGE_UP往上滑动页面。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.toutiao.com/")
driver.maximize_window()
sleep(6)
actions = webdriver.ActionChains(driver)
# 向下翻页
actions.send_keys(Keys.PAGE_DOWN).perform()
# 向上翻页
actions.send_keys(Keys.PAGE_UP).perform()

9 复选框/下拉框操作的Select类

主要使用selinium中的类Select来模拟选择网页上的下拉框或者复选框中的内容,使用前先导入

from selenium.webdriver.support.ui import Select

主要方法如下:

|--------------------------|-----------------|
| 函数 | 功能 |
| select_by_value | 根据复选框/下拉框的值选择 |
| select_by_index | 根据复选框/下拉框的索引选择 |
| select_by_visible_text | 根据复选框/下拉框文本描述选择 |
| deselect_by_value | 根据复选框/下拉框的值反选 |
| deselect_by_index | 根据复选框/下拉框的索引反选 |
| deselect_by_visible_text | 根据复选框/下拉框文本描述反选 |
| deselect_all | 反选所有值 |
| options | 返回所有选项 |
| all_selected_options | 返回所有选中的选项 |
| first_selected_option | 第一个选择的选项 |

我们自定义一个html文件,放一个多选框和下拉框方便测试

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/submit-path">
<label for="fruits">Choose your favorite fruit:</label>
<select id="fruits" name="fruits" multiple>
<option value="apple">Apple</option>
<option value="orange">Orange</option>
<option value="banana">Banana</option>
<option value="grape">Grape</option>
</select>
</form>
<form action="/submit-path">
<label for="animals">Choose your favorite animal:</label>
<select id="animals" name="animals">
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="tiger">Tiger</option>
</select>
</form>
<input type="submit" value="提交" id="su" class="btn self-btn bg s_btn">
</body>
</html>

打开这个html页面如下:一个多选框和一个下拉框

示例:打开html文件,选择多选框内容和下拉框内容。

打开网页,并初始化Select类:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
driver = webdriver.Safari()
# 打开一个网页
driver.get("file:///Users/abc/Desktop/myhtml.html")
driver.maximize_window()
sleep(2)

#初始化Select类,传入水果多选框对应的元素位置
select_content1 = Select(driver.find_element(By.ID,'fruits'))

#初始化Select类,传入动物下拉框对应的元素位置
select_content2 = Select(driver.find_element(By.ID,'animals'))

使用select_by_value函数选择水果多选框第1个和第2个内容

select_content1.select_by_value('apple')
select_content1.select_by_value('orange')

使用deselect_all函数去掉水果多选框的所有的选择

select_content1.deselect_all()

使用select_by_index函数选择动物下拉框的第3个内容

select_content2.select_by_index(2)

执行结果如视频所示:

,时长00:05

10 selenium支持操作滚动条

使用ActionChains 类模拟鼠标滚轮操作

使用函数ActionChains.send_keys发送按键Keys.PAGE_DOWN往下滑动页面,发送按键Keys.PAGE_UP往上滑动页面。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Safari()
# 打开一个网页
driver.get("https://www.toutiao.com/")
driver.maximize_window()
sleep(6)
actions = webdriver.ActionChains(driver)
# 向下翻页
actions.send_keys(Keys.PAGE_DOWN).perform()
# 向上翻页
actions.send_keys(Keys.PAGE_UP).perform()

使用函数execute_script执行js脚本滚动页面

可以使用如下三种方式

1)使用window.scrollBy(x, y)

driver.execute_script('window.scrollBy(0, 1000)')

参数解释:

x:正数表示向右滑动的像素值,负数表示向左滑动的像素值

y:正数表示向下滑动的像素值,负数表示向上滑动的像素值

2)使用window.scrollTo(x, y)

driver.execute_script('window.scrollTo(0, 1000)')

参数解释:

x:正数表示向右滑动到某个像素值,负数表示向左滑动到某个像素值

y:正数表示向下滑动到某个像素值,负数表示向上滑动到某个像素值

3)使用

document.documentElement.scrollTop()设置滚动条高度

设置滚动高度为某个像素值:

driver.execute_script("document.documentElement.scrollTop=1000")

测试代码:使用上面3个️方式向下滚动,然后再向上滚动(中间通过sleep等待几秒方便观察效果).

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
# 打开一个网页
#driver.get("http://www.sahitest.com/demo/framesTest.htm")
driver.get("https://www.toutiao.com/")
driver.maximize_window()
sleep(6)
#向下滚动
driver.execute_script('window.scrollBy(0, 100)')
sleep(1)
driver.execute_script('window.scrollTo(0, 200)')
sleep(1)
driver.execute_script("document.documentElement.scrollTop=300")
sleep(1)
#向上滚动
driver.execute_script('window.scrollBy(0, -100)')
sleep(1)
driver.execute_script('window.scrollTo(0, -200)')
sleep(1)
driver.execute_script("document.documentElement.scrollTop=-300")
sleep(1)

使用函数execute_script执行js脚本滚动到特定元素

我们可以直接找到需要滚动到的元素位置,并使用scrollIntoView方法滚到该位置

示例代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
driver.get("https://www.toutiao.com/")
driver.maximize_window()
sleep(6)
# 找到某个目标元素
element = driver.find_element(By.XPATH,'//*[@id="root"]/div/div[5]/div[2]/div[6]/a[15]')
# 滚动到目标元素
driver.execute_script("arguments[0].scrollIntoView();", element)

11 selenium工具的几种截屏方法

将整个页面截屏

在webdriver模块中有几种截屏的方法,主要介绍如下:

  • save_screenshot(filename)

filename传入以png结尾的文件路径。

  • get_screenshot_as_file (filename)

filename传入以png结尾的文件路径。

  • 还有两个方法保存的是字节码或者字符串

使用get_screensho_as_png函数保存截屏为字节码

使用get_screensho_as_base64函数保存截屏为base64编码后的字符串

driver.get_screenshot_as_png()
driver.get_screenshot_as_base64()

示例:打开头条后,截图

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Safari()
#打开传入的URL网页地址
driver.get("https://www.toutiao.com/")
driver.maximize_window()

使用save_screenshot函数截图保存为png图片

driver.save_screenshot('toutiao1.png')

使用save_screensho_as_filet函数截图保存为png图片

driver.get_screenshot_as_file('toutiao2.png')

12 selenium的IDE插件进行录制和回放并导出为python/java脚本

Selenium IDE:Selenium Suite下的开源Web自动化测试工具,是Firefox或者chrome的一个插件,具有记录和回放功能,无需编程即可创建测试用例,并且可以将用例直接导出为可用的python/java等编程语言的脚本。

我们以chrome浏览器介绍如何使用IDE工具

下载selenium IDE工具

下载插件地址:国内下载地址:https://www.crx4chrome.com/crx/77585/

点击如下红框处的链接下载插件

chrome浏览器导入selenium IDE插件

打开chrome浏览器,按照下图找到'管理扩展程序',

然后将下载的插件拖动到页面上,选择'添加扩展程序'。

添加后如下

chrome浏览器打开selenium IDE插件

按照如下图双击打开插件

选择创建一个新的project

点击ok后,进入如下页面,功能区主要功能标识如下:

开始录制和回放

点击录制按钮,会自动打开chrome浏览器,填写比如百度地址

点击'Start Recording',开始录制,我们输入python点击百度一下进行搜索,然后点击第一个搜索到的内容,最后点击录制按钮结束录制,输入用例名称。

录制后如下,会自动填充整个操作过程,

如果录制有些问题,可以右键某个动作进行删除,或者在该区域中进行修改。

最后点击回放按钮,可以回放这个用例,检验录制是否正确(回放时可以适当调整播放速度)。

导出用例

按照如下图,选择用例,点击'Export'可导出用例。

我们导出基于pytest框架的用例(大家根据实际情况导出其他编程语言的用例,比如java,ruby,C等)

导出后使用pycharm打开用例,如下图,导出的pytest框架用例,格式很清晰,还有setup和teardown功能,大家可以自行修改和调试。

大家不妨在线下尝试下selenium IDE插件,感受下插件的魅力。

13 pytest+selenium进行网页UI自动化测试

pytest安装

使用pip命令安装: pip install pytest -i https://mirrors.aliyun.com/pypi/simple/

pytest框架实现selenium自动化用例

在pytest框架下我们创建1条测试用例,在百度查找内容后,校验下输入框中的内容是不是我们之前输入的内容,具体代码如下:

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
def test_1():
 driver = webdriver.Safari()
 # 打开一个网页
 driver.get("https://www.baidu.com")
 driver.maximize_window()
 driver.find_element(By.ID, 'kw').send_keys('python')
 driver.find_element(By.ID, 'su').click()
 sleep(1)
 assert driver.find_element(By.ID, 'kw').get_attribute('value') == 'python'
 # 等待几秒钟以便观察浏览器行为
 sleep(5)
 # 关闭浏览器
 driver.quit()

用例执行的结果为通过。

我们将用例改造下,通过设置fixture函数来实现用例的setup和teardown动作,并在用例中实现参数化,增加多个搜索的文本。

@pytest.fixture()
def open_close_web():
 driver = webdriver.Safari()
 # 打开一个网页
 driver.get("https://www.baidu.com")
 driver.maximize_window()
 yield driver
 # 关闭浏览器
 driver.quit()

@pytest.mark.parametrize('text',['python','pytest'])
def test_1(text,open_close_web):
 open_close_web.find_element(By.ID, 'kw').send_keys(f'{text}')
 open_close_web.find_element(By.ID, 'su').click()
 sleep(1)
 assert open_close_web.find_element(By.ID, 'kw').get_attribute('value') == f'{text}'

以上代码都实际执行ok。

总结:本章我们简要介绍了使用python库selenium在pytest框架下的UI自动化脚本和用例的编写调试过程,大家可以在线下多多实践,当然对于大型的项目,我们还要规划好整个测试用例和脚本目录结构,方便后续维护。

14 RobotFramework框架+selenium进行UI网页自动化测试

安装RF框架所需的robotframework-seleniumlibrary包

关于RF框架中的selenium包版本说明如下:有两个robotframework-seleniumLibrary和robotframework-selenium2Library

1)robotframework-seleniumLibrary版本说明

robotframework-seleniumLibrary包最新的版本6.5.0(发布时间2024年6月15日),支持Python 3.8到3.11,安装该包时会默认安装依赖的selenium库4.0的版本.

如果自己使用的pyhon版本低于3.8可以参考历史包找到适配的版本(官网地址https://pypi.org/project/robotframework-seleniumlibrary/#history)

每个版本都会有适配的python版本说明:

通过pip命令安装以下包

pip install robotframework-seleniumlibrary安装最新版本或者指定版本

pip install robotframework-seleniumlibrary==5.1.3

2)robotframework-selenium2Library版本说明

robotframework-selenium2Library包最新的版本3.0.0(发布时间2017年12月5日),已经停止更新了。而且从3.0版本开始,Selenium2Library更名为SeleniumLibrary,支持Python 2.7以及Python 3.3及更新版本。

通过pip命令安装包:

pip install robotframework-selenium2library安装最新版本或者指定版本

pip install robotframework-seleniumlibrary==1.8.0

PS: python版本 selenium版本 robotframework-seleniumlibrary版本三个要适配,否则会报错

3)本次使用的RF框架的各个包的适配版本

robotframework-ride 1.7.4

robotframework 3.2.1

robotframework-selenium2library 3.0.0

robotframework-seleniumlibrary 3.3.1

selenium 3.141.0

python 3.7.7

在RF中使用seleniumlibrary库编写用例

1)打开ride导入seleniumlibrary库

打开ride客户端,我们先创建测试套件,然后导入SeleniumLibrary库,按F5键查看一些关键字信息。

2)在SUITE中创建用例

在suite套件中创建一条用例,打开谷歌浏览器,输入文本后点击搜索,返回上一个页面,再次输入后搜索,最后在teardown中关闭浏览器。

以下元素定位的方式采用的是id,大家不妨试下name,class,xpath等方式。

*** Settings ***
Library SeleniumLibrary
*** Variables ***
${URL} https://www.baidu.com
${BROWSER} Chrome

*** Test Cases ***
打开百度输入文本后点击查询
Open Browser ${URL} ${BROWSER}
Input Text id=kw python
click button id=su
${text1} get_value id=kw
#校验输入的内容是否成功
should be equal ${text1} python
sleep 2
go_back
Input Text id=kw selenium
click button id=su
${text1} get_value id=kw
#校验输入的内容是否成功
should be equal ${text1} selenium
sleep 2
${cur_url} log_location
${source} get_source
log ${cur_url}
[Teardown] close_browser

常用关键字介绍

1)浏览器操作相关的关键字

关键字位于文件

SeleniumLibrary/keywords/browsermanagement.py

  • open_browser:打开某个浏览器访问传入的URL,浏览器可以是firefox,chrome,edge,safari等
  • close_all_browsers:关闭打开的所有浏览器
  • close_browser:关闭当前使用的浏览器
  • go_back:返回上一个页面
  • go_to:跳转到其他url
  • reload_page:刷新页面
  • log_location: 返回当前页面的URL
  • location_should_be:返回当前页面的URl 与传入的对比,不相等会报错。

2)表单相关的关键字

关键字位于文件

SeleniumLibrary/keywords/formelement.py

  • submit_form:提交表单
  • select_checkbox:选择某个复选框
  • unselect_checkbox:取消选择某个复选框
  • checkbox_should_be_selected:检查复选框是否被选中
  • checkbox_should_not_be_selected:检查复选框没有被选中
  • page_should_contain_checkbox:检查页面包含某个复选框
  • page_should_not_contain_checkbox:检查页面不包含某个复选框
  • page_should_contain_radio_button:检查页面包含某个单选框
  • page_should_not_contain_radio_button:检查页面不包含某个单选框
  • select_radio_button:选中某个单选框
  • radio_button_should_be_set_to:检查某个单选框设置为某个名称
  • radio_button_should_not_be_selected:检查某个单选框没有被选中
  • choose_file:选择一个文件
  • input_password:输入密码
  • input_text:输入文本
  • page_should_contain_button:检查页面包含某个按钮
  • page_should_not_contain_button:检查页面不包含某个按钮

3)元素相关的关键字

关键字位于文件

SeleniumLibrary/keywords/element.py

  • get_element_attribute:获取元素的属性,比如元素的id,name,value等
  • get_value:获取元素的value值
  • get_text:获取元素的text
  • click_button:点击某个按钮
  • click_image:点击某个图片
  • click_link:点击某个链接
  • click_element:点击某个元素,可以是按钮/图片等
  • double_click_element:双击某个元素
  • mouse_down:鼠标往下移动
  • mouse_out:鼠标移出
  • mouse_over:鼠标悬停
  • mouse_up:鼠标往上移动

4)窗口相关的关键字

关键字位于文件

SeleniumLibrary/keywords/window.py

  • maximize_browser_window:最大化窗口
  • set_window_size:设置窗口的大小
  • close_window:关闭浏览器窗口

共勉: 东汉·班固《汉书·枚乘传》:"泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。"

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。

----感谢读者的阅读和学习,谢谢大家。

相关推荐
hummhumm13 分钟前
Oracle 第13章:事务处理
开发语言·数据库·后端·python·sql·oracle·database
童先生18 分钟前
python 用于请求chartGpt DEMO request请求方式
开发语言·python
朝九晚五ฺ18 分钟前
【Linux探索学习】第九弹——Linux工具篇(四):项目自动化构建工具—make/Makefile
linux·运维·学习·ubuntu·自动化
Narutolxy3 小时前
探索开源语音识别的未来:高效利用先进的自动语音识别技术20241030
python·macos·xcode
Mopes__5 小时前
Python | Leetcode Python题解之第517题超级洗衣机
python·leetcode·题解
测试老哥7 小时前
Python+Selenium+Pytest+POM自动化测试框架封装(完整版)
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
Ws_7 小时前
蓝桥杯 python day01 第一题
开发语言·python·蓝桥杯
神雕大侠mu8 小时前
函数式接口与回调函数实践
开发语言·python
萧鼎9 小时前
【Python】高效数据处理:使用Dask处理大规模数据
开发语言·python
独行soc9 小时前
#渗透测试#红蓝对抗#Src漏洞挖掘 介绍-Yakit(3)
测试工具·web安全·网络安全·yakit·护网