Web自动化测试
Web自动化测试就是由机器设备代替人为自动完成指定目标的过程叫做自动化
让程序代替人为去验证系统功能的过程
自动化测试能解决什么问题
解决回归测试、压力测试、兼容性测试,提高测试效率,保证产品质量
什么Web项目适合做自动化测试
1、需求变动不频繁
2、项目需要回归测试
3、项目周期长
web自动化环境搭建
所需程序:
Selenium
浏览器驱动
浏览器
具体执行流程:
1、程序员先通过Selenium工具编写如何操作浏览器的Python代码
2、当运行编写好的Python代码的时候会调用对应的浏览器驱动
3、浏览器驱动会启动对应的浏览器,把Python代码操作浏览器的效果会呈现出来。
Selenium
Selenium是一系列基于Web的自动化工具,主要用于Web自动化测试。它能够模拟人来操作浏览器,完成界面元素定位、窗口跳转、结果比较等功能。具有特点:支持多浏览器、多种语言、多种操作系统、开源免费。
Selenium安装
使用Python提供的pip工具进行安装
pip:是 Python 的包管理工具,主要提供了对 Python 第三方包或者模块安装和卸载的功能。
安装Selenium命令如下:
1、打开终端
2、windows系统使用【pip install selenium】 , mac系统使用 【pip3 install selenium】
浏览器驱动下载及配置
根据不同的浏览器版本下载对应的浏览器驱动,下载的驱动与浏览器版本不一致无法进行使用!
谷歌浏览器驱动下载:http://npm.taobao.org/mirrors/chromedriver/
火狐浏览器驱动下载:https://npm.taobao.org/mirrors/geckodriver/
IE浏览器驱动下载: https://npm.taobao.org/mirrors/selenium/
Edge驱动下载:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
浏览器驱动下载完成以后放到已经添加到环境变量的目录中即可,如Python安装的目录中。以谷歌驱动为例,下载放入之后在终端输入 【chromedriver】 出现对应版本信息说明配置成功。
web自动化入门示例
需求:通过程序启动浏览器,并打开百度首页,暂停3秒,关闭浏览器
# 1. 导包
import time
from selenium import webdriver
# 2. 创建浏览器驱动对象
driver = webdriver.Chrome() # Chrome浏览器
# driver = webdriver.Firefox() # Firefox浏览器
# driver = webdriver.Ie() # IE浏览器
# 3. 打开Web页面
driver.get("https://www.baidu.com/")
# 4. 暂停3秒
time.sleep(3)
# 5. 关闭驱动对象
driver.quit()
注意:如果访问不到浏览器则需要自定义浏览器路径,如下:
# 创建浏览器驱动对象
options = webdriver.ChromeOptions()
options.binary_location = r"C:Users李阳AppDataLocalCentBrowserApplicationchrome.exe"
driver = webdriver.Chrome(chrome_options=options)
元素定位
Selenium元素定位的方式
1、id
2、name
3、class_name
4、tag_name
5、link_text
6、partial_link_text
7、Xpath
8、CSS
元素定位实现步骤
1. 导入selenium包 --> from selenium import webdriver
2. 导入time包 --> from time import sleep
3. 实例化谷歌浏览器 --> driver=webdriver.Chrome()
4. 打开注册url --> driver.get(url)
5. 调用元素定位方法 --> driver.元素定位方法("")
6. 使用send_keys()方法发送数据 --> .send_keys("数据")
7. 暂停3秒 --> sleep(3)
8. 关闭浏览器驱动对象 --> quit()
1、id定位
id定位就是通过元素的id属性来定位元素,HTML规定id属性在整个HTML文档中必须是唯一的。
id定位方法:
element = driver.find_element_by_id(id)
例:
# 导包
import time
from selenium import webdriver
# 创建浏览器驱动对象
driver = webdriver.Chrome()
# 打开web网页
driver.get("https://www.baidu.com/")
# 通过id定位搜索标签
find = driver.find_element_by_id("kw")
bd = driver.find_element_by_id("su")
# 暂停
time.sleep(1)
# 发送数据
find.send_keys("河南")
# 点击
bd.click()
time.sleep(5)
# 关闭浏览器驱动对象
driver.quit()
2、name定位
name定位就是根据元素name属性来定位。HTML规定name属性来指定元素名称。
name定位方法:
element = driver.find_element_by_name(name)
3、class_name定位
class_name定位就是根据元素class属性值来定位。HTML通过使用class来定义元素的样式。
注意:使用class_name定位是必须有class属性,如果class有多个属性值,只能使用其中的一个
class_name定位方法:
element = driver.find_element_by_class_name(class_name)
4、tag_name定位
tag_name定位就是通过标签名来定位;HTML本质就是由不同的tag组成,每一种标签一般在页面中会存在多个,所以不方便进行精确定位,一般很少使用
注意:如果存在多个相同标签,则返回符合条件的第一个标签;如何获取第二个元素,可以根据下标或者标签的属性获取对应的元素。
tag_name定位方法:
element = driver.find_element_by_tag_name(tag_name)
5、link_text定位
link_text定位与前面4个定位有所不同,它专门用来定位超链接元素(<a>标签</a>
)
注意:传值时需要传入a标签全部文本,如<a href="http://news.baidu.com/">新闻</a>
则需要把【新闻】传入进去
link_text定位方法:
element = driver.find_element_by_link_text(link_text)
6、partial_link_text定位
partial_link_text定位是对link_text定位的补充,partial_link_text为模糊匹配;link_text全部匹配
partial_link_text定位方法:
driver.find_element_by_partial_link_text(partial_link_text)
7、XPath定位
XPath 使用路径表达式来选取 XML/HTML 文档中的节点或节点集的。
xpath基本语法:
表达式 | 描述 |
---|---|
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
路径表达式 | 结果 |
---|---|
bookstore | 选取 bookstore 节点。 |
/bookstore | 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
xpath中的高级语法:
路径表达式 | 结果 |
---|---|
//bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
//bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
//bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
//bookstore/book[position()<3 ] |
选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@data] | 选取所有拥有名为 data 的属性的 title 元素。 |
//title[@data='777'] | 选取所有 title 元素,且这些元素拥有值为 777 的 data 属性。 |
//title[contains(@data,'7')] | 选取所有 title 元素,且这些元素拥有值包含 7 的 data 属性。 |
//bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
//bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
XPath 通配符可用来选取未知的 html 元素
通配符 | 描述 |
---|---|
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
//bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
使用 | 符号选择多种标签
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取 bookstore 元素的 book 元素的所有 title 元素和所有的 price 元素。 |
XPath定位方法:
element = driver.find_element_by_xpath(xpath)
示例:
# 1. 导包
import time
from selenium import webdriver
# 2. 创建浏览器驱动对象
driver = webdriver.Chrome()
# 3. 打开Web页面
driver.get("http://news.baidu.com/")
# 通过 XPath定位方法
a_element = driver.find_element_by_xpath("//a[text()='图片']")
# 点击
a_element.click()
# 4. 暂停
time.sleep(5)
# 5. 关闭驱动对象
driver.quit()
注意:如果XPath不会写可以打开浏览器对应的页面数据右击【检查】 --> 代码块上右击【Copy】 --> 选择【Copy XPath】即可复制对应的XPath
8、css定位
css选择器 | 案例 | 说明 |
---|---|---|
#id | #user | id选择器,选择id="user"的所有元素 |
.class | .Tel | class选择器,选择class="Tel"的所有元素 |
element | input | 选择所有input标签 |
[attribute=value] | [type="pswd"] | 选择type="pawd"的所有元素 属性的值要用单引号或双引号 |
element>element | p>input | 选择所有父元素为p元素的input元素 可以用空格代替 |
* | * | 选择所有元素 |
css定位方法:
element = driver.find_element_by_css_selector(css选择器)
示例:
# 1. 导包
import time
from selenium import webdriver
# 2. 创建浏览器驱动对象
driver = webdriver.Chrome()
# 3. 打开Web页面
driver.get("http://news.baidu.com/")
time.sleep(1)
# 通过 css定位方法
# 注意:CSS支持多个class选择器同时进行使用
url_element = driver.find_element_by_css_selector(".ulist.focuslistnews").text
print(url_element)
# 4. 暂停
time.sleep(3)
# 5. 关闭驱动对象
driver.quit()
定位一组元素
find_element[s]_by_XXX()
作用:
1、查找定位所有符合条件的元素
2、返回的定位元素格式为数组(列表)格式;
说明:
列表数据格式的读取需要指定下标(下标从0开始)
例:
# 获取所有input元素
driver.find_elements_by_tag_name("input")
# 使用tag_name获取第二个元素(密码框)
# driver.find_elements_by_tag_name("input")[1].send_keys("123456")
driver.find_element_by_xpath("//input")[1].send_keys("123456")
元素操作和浏览器操作
元素常用操作方法
元素常用操作方法
clear() # 清除文本
send_keys() # 模拟输入
click() # 单击元素
这里以百度为例
driver.get("https://www.baidu.com")
获取元素文本
语法:元素.text
element = driver.find_element_by_id("s-usersetting-top")
# 获取元素文本内容
print(element.text)
获取元素大小
语法:元素.size
element = driver.find_element_by_id("su")
# 获取元素大小,以字典的方式进行输出
print(element.size)
根据元素属性获取属性值
语法:元素.get_attribute("属性名")
element = driver.find_element_by_id("su")
# 根据元素属性获取属性值
print(element.get_attribute("value"))
获取元素的可用状态
语法:元素.is_enabled()
说明:可用返回true,不可用返回false
element = driver.find_element_by_id("su")
# 根据元素属性获取属性值
print(element.is_enabled())
获取元素的可见状态
语法: 元素.is_displayed()
说明: 可见返回true,不可见返回false
element = driver.find_element_by_id("su")
# 根据元素属性获取属性值
print(element.is_displayed())
浏览器常用操作方法
浏览器窗口操作
maximize_window() # 浏览器最大化 --> 模拟浏览器最大化按钮
set_window_size(Width, height) # 浏览器大小 --> 设置浏览器宽、高(像素点)
set_window_position(x, y) # 浏览器位置 --> 设置浏览器位置
示例:
# 浏览器你最大化
driver.maximize_window()
# 设置浏览器窗口大小
driver.set_window_size(400, 300)
# 设置浏览器位置
driver.set_window_position(100, 100)
页面的回退前进刷新
back() # 后退 --> 模拟浏览器后退按钮
forward() # 前进 --> 模拟浏览器前进按钮
refresh() # 刷新 --> 模拟浏览器F5刷新
示例:
# 回退
driver.back()
# 前进
driver.forward()
# 刷新
driver.refresh()
关闭窗口
close() # 关闭 --> 模拟浏览器关闭按钮(关闭当前窗口)
quit() # 关闭 --> 关闭所有 webdriver 启动的窗口
获取当前网页标题和地址
# 获取标题
语法: driver.title
# 获取地址
语法: driver.current_url
示例:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 获取当前网页的标题
title = driver.title
print("当前网页的标题:", title)
# 获取当前窗口的网址
url = driver.current_url
print("当前窗口的网址:", url)
driver.quit()
鼠标和键盘的操作
现在Web产品中提供了丰富的鼠标交互方式,如:单击、双击、悬停、拖拽等功能,做为Web产品测试
鼠标操作
操作鼠标方法
说明:操作鼠标的方法封装在ActionChains类中
click() # 左击 --> 此方法模拟鼠标左键点击效果
context_click() # 右击 --> 此方法模拟鼠标右键点击效果
double_click() # 双击 --> 此方法模拟双标双击效果
drag_and_drop() # 拖动 --> 此方法模拟双标拖动效果
move_to_element() # 悬停 --> 此方法模拟鼠标悬停效果
perform() # 执行 --> 此方法用来执行以上所有鼠标方法
鼠标方法的使用
提示:使用前需要导入ActionChains类
from selenium.webdriver import ActionChains
语法:
ActionChains(driver).鼠标操作方法(操作的元素).perform()
注意:必须调用perform()方法才能执行鼠标事件!
click() - 鼠标左键
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
# 创建浏览器驱动对象
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element_by_id("kw").send_keys("河南")
search_button = driver.find_element_by_id("su")
# click() - 鼠标左键
ActionChains(driver).click(search_button).perform()
time.sleep(3)
driver.quit()
context_click() - 鼠标右键
element = driver.find_element_by_id("kw")
# context_click() - 鼠标右键
ActionChains(driver).context_click(element).perform()
double_click() - 鼠标双击
element = driver.find_element_by_id("kw")
element.send_keys("河南")
# double_click() - 鼠标双击
ActionChains(driver).double_click(element).perform()
drag_and_drop() - 鼠标拖动
driver.get("http://sahitest.com/demo/dragDropMooTools.htm")
div1 = driver.find_element_by_id("dragger")
div2 = driver.find_element_by_xpath("//div[text()='Item 1']")
# drag_and_drop() - 鼠标拖动
ActionChains(driver).drag_and_drop(div1, div2).perform()
move_to_element() - 鼠标悬停
element = driver.find_element_by_xpath("//a[text()='更多']")
# move_to_element() - 鼠标悬停
ActionChains(driver).move_to_element(element).perform()
键盘操作
说明:
模拟键盘上一些按键或者组合键的输入,如:Ctrl+C 、Ctrl+V;
WebDriver中对键盘的操作都封装在Keys类中
注意:
windows上的 Ctrl 键 等价于 mac上的 Command键
提示:
使用前需要导入Keys()类
from selenium.webdriver.common.keys import Keys
常用的键盘操作
send_keys(Keys.BACK_SPACE) # 删除键(BackSpace)
send_keys(Keys.SPACE) # 空格键(Space)
send_keys(Keys.TAB) # 制表键(Tab)
send_keys(Keys.ESCAPE) # 回退键(Esc)
send_keys(Keys.ENTER) # 回车键(Enter)
send_keys(Keys.CONTROL, 'a') # 全选(Ctrl+A)
send_keys(Keys.CONTROL, 'c') # 复制(Ctrl+C)
# 注意:组合件的的 a、c、v 使用小写字母
案例:
"""
需求:
1). 输入手机号:131888888881 暂停2秒,删除1
2). 全选手机号:13188888888 暂停2秒
3). 复制手机号:13188888888 暂停2秒
4). 粘贴到手机号框 暂停2秒
5). 关闭浏览器
"""
import platform
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 创建浏览器驱动对象
options = webdriver.ChromeOptions()
options.binary_location = r"C:Users李阳AppDataLocalCentBrowserApplicationchrome.exe"
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://reg.jd.com/e/regPage?source=biguser&tgId=S-qtktaHl2k")
driver.maximize_window()
userA = driver.find_element_by_id("input_account")
userA.send_keys("131888888881")
time.sleep(2)
userA.send_keys(Keys.BACK_SPACE)
time.sleep(2)
print(platform.system())
ctrl = None
# 判断操作系统
if platform.system() == "Windows":
ctrl = Keys.CONTROL
else:
ctrl = Keys.COMMAND
userA.send_keys(ctrl, "a", "c")
time.sleep(1)
userA = driver.find_element_by_id("input_phone").send_keys(ctrl, "v")
time.sleep(3)
driver.quit()
下拉框、弹出框、滚动操作
下拉框
下拉框就是HTML中<select>
元素;
提示:使用前需要导入Select类,此类定位的是select标签
select方法:
select_by_index() # 根据option索引来定位,从0开始
select_by_value() # 根据option属性 value值来定位
select_by_visible_text() # 根据option显示文本来定位
示例:
import time
from selenium import webdriver
# 导入 Select类
from selenium.webdriver.support.select import Select
# 创建浏览器驱动对象
options = webdriver.ChromeOptions()
options.binary_location = r"C:Users李阳AppDataLocalCentBrowserApplicationchrome.exe"
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://www.jq22.com/yanshi23619")
# 切换到 iframe
driver.switch_to.frame("iframe")
element = driver.find_element_by_id("province")
select = Select(element)
# 调用对应的操作方法
select.select_by_index(1)
time.sleep(1)
select.select_by_value("河南省")
time.sleep(1)
select.select_by_visible_text('湖北省')
time.sleep(3)
driver.quit()
弹出框
弹出框有三种方式:
1、alert:普通弹出框
2、confirm:带取消按钮的弹出框
3、prompt:带输入框和取消按钮的输入框
切换到弹出框:必须要切换到弹出框,否则无法进行相关操作
# 切换到弹出框
alert = driver.switch_to.alert
弹出框的处理方法
text # 返回alert/confirm/prompt中的文字信息
accept() # 接受对话框选项
dismiss() # 取消对话框选项
send_keys() # 输入内容
示例:
import time
from selenium import webdriver
# 创建浏览器驱动对象
options = webdriver.ChromeOptions()
options.binary_location = r"C:Users李阳AppDataLocalCentBrowserApplicationchrome.exe"
driver = webdriver.Chrome(chrome_options=options)
# driver = webdriver.Firefox()
driver.get("file:///D:/Test Program/PyCharm 2021.1.2/PycharmProjects/素材/注册A.html")
# # alter的使用
# driver.find_element_by_id("alerta").click()
# time.sleep(2)
# alter = driver.switch_to.alert
# print(alter.text)
# alter.accept()
# prompt的使用
driver.find_element_by_xpath("//input[@value='Click For Prompt']").click()
time.sleep(1)
prompt = driver.switch_to.alert
prompt.send_keys("你好!")
time.sleep(1)
prompt.accept()
time.sleep(3)
driver.quit()
页面滚动
Selenium类库中并没有直接提供对滚动条进行操作方法,但是它提供了可调用 JavaScript脚本的方法让页面进行滚动,所以我们可以通过JavaScript脚本来达到操作滚动条的目的。
# 1. 设置JavaScript脚本控制滚动条
js = "window.scrollTo(0, 1000)"
# window.scrollTo(0:左边距;1000:上边距) 单位像素
# 2. WebDriver调用js脚本方法
driver.execute_script(js)
示例:
需求:打开京东,两秒后滚动条往下拉
import time
driver = webdriver.Chrome()
driver.get("https://www.jd.com/")q
time.sleep(2)
driver.execute_script("window.scrollTo(0, 4000)")
time.sleep(3)
driver.quit()
Frame
HTML页面中的一种框架,主要作用是在当前页面中指定区域显示另一页面元素;
frame 切换:
# 切换方法(frame1:为frame表单的name或id)
driver.switch_to.frame("frame1")
# 恢复默认页面方法(在frame中操作其他页面,必须先回到默认页面,才能进一步操作)
driver.switch_to.default_content()
案例:
把当前页面的用户名 “admin” 复制到 frame1的用户名中
再把 frame1中的用户名复制到 frame2的用户名中
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 创建浏览器驱动对象
driver = webdriver.Chrome()
driver.get("file:///D:/Test Program/PyCharm 2021.1.2/PycharmProjects/素材/注册实例.html")
iframe = driver.find_elements_by_xpath("//body//iframe")[:2]
user = driver.find_element_by_id("user")
user.send_keys("admin")
user.send_keys(Keys.CONTROL, "a", "c")
time.sleep(1)
# 切换到frame1
driver.switch_to.frame(iframe[0])
driver.find_element_by_id("userA").send_keys(Keys.CONTROL, "v")
# 切换到默认页面
driver.switch_to.default_content()
time.sleep(1)
# 切换到frame2
driver.switch_to.frame(iframe[1])
driver.find_element_by_id("userB").send_keys(Keys.CONTROL, "v")
time.sleep(3)
driver.quit()
多窗口切换
在Selenium中封装了 获取当前窗口句柄方法 和 获取所有窗口句柄 的方法以及切换指定句柄窗口的方法;(句柄:英文handle,窗口的唯一识别码)
为什么要切换窗口
当链接A跳转到链接B时,链接B无法直接进行操作,因为默认操作的还是链接A窗口,如果需要操作链接B 需要切换窗口。
方法:
driver.current_window_handle # 获取当前窗口句柄
driver.window_handles # 获取所有窗口句柄
driver.switch_to.window(handle) # 切换指定句柄窗口
示例:
打开百度界面,点击新闻链接,在新闻链接窗口点击音乐链接
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
time.sleep(1)
driver.find_element_by_xpath("//a[text()='新闻']").click()
print("当前窗口:", driver.current_window_handle)
# 获取所有窗口
window = driver.window_handles
print("所有窗口:", window)
print("最后一个窗口:", window[-1])
# window[-1]:获取最后一个窗口
driver.switch_to.window(window[-1])
driver.find_element_by_xpath("//a[text()='音乐']").click()
time.sleep(3)
driver.quit()
窗口截图
为什么要窗口截图
自动化脚本是由程序去执行的,因此有时候打印的错误信息并不是十分明确。如果在执行出错的时候对当前窗口截图保存,那么通过图片就可以非常直观地看到出错的原因。
窗口截图
方法:
# 截取当前窗口(imgpath:图片保存路径)
get_screenshot_as_file(imgpath)
示例:
打开hao123页面,向下滚动1000像素进行截图保存
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.hao123.com/")
# 向下移动1000像素
driver.execute_script("window.scrollTo(0, 1000)")
time.sleep(2)
# 获取屏幕截图
driver.get_screenshot_as_file("imgs/hao123.png")
time.sleep(3)
driver.quit()
截取全屏
import time
from selenium import webdriver
# 截取全屏, 设置无头浏览器,也就是没有界面浏览器
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--dns-prefetch-disable')
options.add_argument('--no-referrers')
options.add_argument('--disable-gpu')
options.add_argument('--disable-audio')
options.add_argument('--no-sandbox')
options.add_argument('--ignore-certificate-errors')
options.add_argument('--allow-insecure-localhost')
# 创建浏览器驱动对象
driver = webdriver.Chrome(options=options)
# 浏览器最大化
driver.maximize_window()
# 打开网页,注册实例.html
driver.get("https://www.hao123.com/")
# 设置窗口大小
width = driver.execute_script("return document.documentElement.scrollWidth")
height = driver.execute_script("return document.documentElement.scrollHeight")
print(width, height)
# 将浏览器的宽高设置成刚刚获取的宽高
driver.set_window_size(width, height)
time.sleep(3)
# 对当前页面进行截图保存, 默认只是截取当前屏幕。存放多级目录下需要目录存在
driver.get_screenshot_as_file("info.png")
time.sleep(3)
driver.quit()
Cookie
Cookie是什么
Cookie是浏览器保存服务器的一小段文本信息,标识不同用户的;格式:python中的字典(键值对组成)
Cookie产生:客户端请求服务器,如果服务器需要记录该用户状态,就向客户端浏览器颁发一个Cookie格式
Cookie使用:当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器,服务器检查该Cookie,以此来辨认用户状态。
Cookie的作用
1、用户第一次登陆时,勾选下次直接登陆或者记住密码,就是采用记录Cookie实现的
2、Cookie内记录用户名和密码(加密)信息,只要请求时服务器收到Cookie就识别成功,默认为已登陆。
Cookie使用方法
get_cookie(name) # 获取指定cookie(name:为健名)
get_cookies() # 获取本网站所有本地cookies
add_cookie(dict) # 添加cookie(dict:为python中的字典格式)
示例:
前提:先登录百度,获取对应的Cookie
打开百度,添加Cookie,使其自行登录
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://baidu.com/")
# 添加Cookie
driver.add_cookie({'name': 'BDUSS', 'value': '更换成BDUSS的值'})
time.sleep(2)
# 获取所有cookie
cookies = driver.get_cookies()
print("请求前获取所有cookie:", cookies)
# 根据cookie的名字获取对应cookie值,返回的是一个字典
value = driver.get_cookie("BDUSS")
print("BDUSS的cookie对应的值为:", value)
# 根据字典获取value值
print("Cookie对应的BDUSS值为:", value["value"])
# 刷新页面
driver.refresh()
time.sleep(3)
driver.quit()
元素等待
Selenium定位页面元素时如果未找到,会在指定时间内一直等待的过程。
元素等待类型
强制等待
显示等待
隐式等待
强制等待 - sleep()
使用方法:
sleep(X),等待X秒后,进行下一步操作。
一般使用sleep(X)强制让浏览器等待X秒,不管当前操作是否完成,是否可以进行下一步操作,都必须等X秒的时间。
显示等待 - WebDriverWait()
使用方法:
使用前需要先导入
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait()会配合 until() 和 **until_not() ** 方法一起使用
WebDriverWait(driver, timeout, poll_frequency=1, ignored_exceptions=None).until(要执行的方法)
# driver:浏览器实例
# timeout:超时时间,默认已秒为单位
# poll_frequency:检测时间间隔,默认0.5秒
# ignored_exceptions:报错信息,默认抛出NoSuchElementException
# 示例:
element = WebDriverWait(driver, 10, 1).until(lambda current_driver: current_driver.find_element_by_id("ddddd"))
示例:
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
# 创建浏览器驱动对象
driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
# 显示等待
# WebDriverWait(driver, 超时时间, 每多少秒请求一次)
span_element = WebDriverWait(driver, 10, 1).until(lambda current_driver: current_driver.find_element_by_id("s-usersetting-top"))
print(span_element.text)
time.sleep(3)
driver.quit()
总结:
1、显示等待超过指定时间没有找到元素,则抛出一个时间超时的异常(TimeoutException)
2、当在指定超时时间内找到了该元素则停止等待,代码继续往下执行。
3、显示等待只作用于1个元素
4、如果没有找到元素则会在指定时间内进行等待,否则上来就找到了该元素则不会等待。
隐式等待 - implicitly_wait()
使用方法:
# time_to_wait:等待的时间,单位秒
driver.implicitly_wait(time_to_wait)
WebDriver类下的 implicitly_wait(X),在X时间内,页面加载完成,进行下一步操作
implicitly_wait()默认是等待时间是0,同时隐性等待是对driver起作用,所以只要设置一次即可,比强制等待更智能
示例:
import time
from selenium import webdriver
# 创建浏览器驱动对象
driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
# 隐式等待10秒
driver.implicitly_wait(10)
element = driver.find_element_by_id("s-usersetting-top")
print(element.text)
time.sleep(3)
driver.quit()
总结:
1、当使用隐藏等待超过指定时间没有找到指定元素会抛出元素没有找到的异常(NoSuchElementException)
2、当在指定的时间内找到了指定元素,则不会在继续等待,代码会继续往下执行。
3、隐式等待会作用域所有标签,当元素没有找到的时候会触发隐式等待。
4、如果上来没有找到指定元素则会进行隐式等待,否则上来找到了指定元素不会触发隐式等待。
*显示等待和隐式等待的区别
不同点:
1、显示等待超过指定时间没有找到指定元素则会抛出超时异常(TimeoutException),
隐式等待超过指定时间没有找到元素,则抛出NoSuchElementException
2、显示等待只能作用于某个元素;而隐式等待会作用域所有元素,当某个元素没有找到的时候会触发隐式等待。
3、显示等待是通过WebDriverWait类来完成的,隐式等待是通过浏览器驱动对象来完成。
共同点:
1、不管是隐式等待还是显示等待,当找不到某个元素的时候会触发相关的等待操作,当某个元素在指定的时间找到后则不会在继续等待,等待会结束
unittest 框架
unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果。
unittest框架是Python自带的,所以不需要使用pip命令进行安装。
unittest框架的使用步骤:
1、导包 import unittest
2、自定义一个测试类,继承unittest.TestCase, 最好类名也要以Test开头
3、在自己的测试类里面写的测试方法必须以 test开头
unittest相关属性
unittest.TestCase:TestCase类,所有测试用例类继承的基本类
unittest.main():可以将一个单元测试模块变为可直接运行的测试脚本
unittest.TestSuite():unittest框架的TestSuite()类是用来创建测试套件的
unittest.TextTestRunner(verbosity=2):unittest框架的TextTestRunner()类,通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。verbosity 表示测试的详细信息,默认verbosity=1
unittest.defaultTestLoader():defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover。
discover = unittest.defaultTestLoader.discover("./", pattern="test_*.py")
TestCase类的属性
setUp()方法:用于测试用例执行前的初始化工作。如测试用例中需要访问数据库,可以在setUp中建立数据库连接并进行初始化。如测试用例需要登录web,可以先实例化浏览器。
tearDown()方法:用于测试用例执行之后的善后工作。如关闭数据库连接、关闭浏览器。
assert*():一些断言方法。在执行测试用例的过程中,判断测试得到的实际结果和预期结果是否一致。
断言方法 | 断言描述 |
---|---|
assertEqual(arg1, arg2, msg=None) | 验证arg1=arg2,不等则fail |
assertNotEqual(arg1, arg2, msg=None) | 验证arg1 != arg2, 相等则fail |
assertTrue(expr, msg=None) | 验证expr是true,如果为false,则fail |
assertFalse(expr,msg=None) | 验证expr是false,如果为true,则fail |
assertIsNone(expr, msg=None) | 验证expr是None,不是则fail |
assertIsNotNone(expr, msg=None) | 验证expr不是None,是则fail |
assertIn(arg1, arg2, msg=None) | 验证arg1是arg2的子串,不是则fail |
示例:
# unittest框架是Python自带的,所以不需要使用pip命令进行安装
import unittest
# 自定义一个测试类
class TestLogin(unittest.TestCase):
# -> None 表示方法没有返回值,加不加都可以
def setUp(self) -> None:
# 主要完成测试的初始化工作,比如:创建浏览器驱动对象
print("测试用例方法执行之前先执行setUp方法!")
def tearDown(self) -> None:
# 主要完成测试的收尾工作,比如: 关闭浏览器驱动对象
print("测试用例方法执行完毕后会执行tearDown方法!")
# 登录成功的测试用例方法
def test_success_login(self):
print("登录成功的测试用例执行啦...")
assert "首页" == "首页"
# 登录失败的测试用例方法
def test_fail_login(self):
print("登录失败的测试用例执行啦...")
assert False
# 判断是否是主模块
if __name__ == '__main__':
unittest.main()
TestSuite类的属性
addTest()方法:将测试用例添加到测试套件中
# suite.addTest(类名("方法名字符串"))
# suite.addTest(TestLogin("test_success"))
# suite.addTest(TestRegister("test_register"))
# test_cases = [类名1("方法名字符串"),类名2("方法名字符串")]
suite_list = [
TestLogin("test_success"),
TestRegister("test_register")
]
suite.addTests(suite_list)
TextTestRunner类的属性
表示测试的执行器,它是用于执行测试套件,把测试套件中每一个测试方法都要去执行
run()方法:是运行测试套件的测试用例,入参为suite测试套件。
案例:
模拟登陆QQ邮箱
注意:编写的测试用例方法需以 test 开头
import time
import unittest
from selenium import webdriver
# 登录QQ邮箱测试
class TestVisit(unittest.TestCase):
# 执行之前
def setUp(self) -> None:
# 创建浏览器驱动对象
self.driver = webdriver.Chrome()
# 窗口最大化
self.driver.maximize_window()
# 设置隐式等待,防止元素没有准备好
self.driver.implicitly_wait(10)
self.driver.get("https://mail.qq.com/")
# 定位frame元素
self.driver.switch_to.frame("login_frame")
self.driver.find_element_by_id("switcher_plogin").click()
# 执行之后
def tearDown(self) -> None:
time.sleep(5)
self.driver.quit()
def common_test_param(self, user, pwd):
time.sleep(1)
self.driver.find_element_by_id("u").send_keys(user)
time.sleep(1)
self.driver.find_element_by_id("p").send_keys(pwd)
time.sleep(2)
self.driver.find_element_by_id("login_button").click()
# 登录失败
# 编写的测试用例方法需以 test开头
def test_err(self):
self.common_test_param("2411135390@qq.com", "64147515")
err_m = self.driver.find_element_by_id("err_m")
time.sleep(0.5)
assert err_m.text == "你输入的帐号或密码不正确,请重新输入。", "断言失败,帐号或密码不正确!"
# 登录成功
def test_success(self):
self.common_test_param("2411135390@qq.com", "64147515*.")
self.driver.switch_to.window(self.driver.window_handles[-1])
exits = self.driver.find_element_by_xpath("//a[text()='退出']")
time.sleep(0.5)
assert exits.text == "退出", "登录成功!"
if __name__ == '__main__':
TestVisit.mian()
PO模式
PO模式的全名叫做Page Object:页面-对象模式。适用于UI自动化编程。
核心思想:每一个操作的页面都抽象一个对应的类,页面中使用的元素封装属性,对元素的操作封装方法。
优点:方便管理和提高代码的可维护型、复用性。
案例:
使用PO模式测试京东搜索
说明:
base包:管理页面的公共操作模块
page包:管理每个页面的抽象模块
scripts包:管理业务操作模块
report:生成报告目录
main.py:程序入口模块