欢迎来到啊妮莫的学习小屋🎉


个人主页🎪: 啊妮莫的学习小屋

收录专栏📚: 软件测试

本文是UI自动化测试保姆级教程②的续篇, 如果还没有看过的小伙伴, 可以点击链接跳转直达哦~

话不多说, 让我们开始学习吧!


目录

下拉框

​编辑传统处理方案

Select类处理

弹出框

系统弹窗

自定义弹窗

滚动条

frame处理

切换frame操作

多窗口处理

截图操作

时间戳防止图片重名被覆盖

验证码

面试题: 常见的验证码处理策略

cookie绕过原理


下拉框

下拉选择框操作
说明:下拉框就是HTML中<select>元素;


传统处理方案

代码示例:

"""
下拉框处理: 传统方案
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

# 需求:使用‘注册A.html’页面,完成对城市的下拉框的操作
# 1).选择‘广州’
driver.find_element(By.CSS_SELECTOR,'[value="gz"]').click()
sleep(2)
# 2).暂停2秒,选择‘上海’
driver.find_element(By.CSS_SELECTOR,'[value="sh"]').click()
sleep(2)
# 3).暂停2秒,选择‘北京’
driver.find_element(By.CSS_SELECTOR,'[value="bj"]').click()

# 结论: 可以通过直接定位下拉框中的内容对应的元素, 完成对下拉框元素的处理!

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

Select类处理

实例化Select对象后, 可以调用以下方法进行下拉框选择:

# 通过索引选择目标元素(索引从 0 开始)
Select对象.select_by_index(n)

# 通过 value 属性值选择目标元素
Select对象.select_by_value('value值')

# 通过可见文本信息选择目标元素
Select对象.select_by_visible_text('文本信息')

代码示例:

"""
下拉框操作: Select 类的使用
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

# 需求:使用‘注册A.html’页面,完成对城市的下拉框的操作
# 0> 定位下拉框元素
sel = driver.find_element(By.ID, 'selectA')
# 1> 实例化下拉框选择对象
se = Select(sel)
# 1).选择‘广州’
# 2> 通过索引选择目标元素(索引从 0 开始)
se.select_by_index(2)
sleep(2)
# 2).暂停2秒,选择‘上海’
# 2> 通过 value 属性值选择目标元素
se.select_by_value('sh')
sleep(2)
# 3).暂停2秒,选择‘北京’
# 2> 通过可见文本信息选择目标元素
se.select_by_visible_text('北京')

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

注意:
1.如果页面内需要操作的下拉框元素有多个,需要根据目标下拉框,依次实例化下拉框选择对象
2.根据具体需求,三种下拉框内容元素选择方法,任选其一使用即可!!!!!

弹出框

应用场景

页面操作过程中,一旦出现弹窗,如果不进行处理,则后续操作无法执行!
弹窗分类

  1. 系统弹窗(JS实现)
  2. 自定义弹窗(前端代码封装)

系统弹窗

对于系统弹窗可以通过以下三步进行处理:

# 1> 切换到弹窗: 只要是系统弹窗, 无论哪一种, 处理方法都是以下的步骤!!!!!!
alert = driver.switch_to.alert

# 2> 获取弹窗信息(可选): 获取弹窗信息必须在处理弹窗操作之前!
print('弹窗信息是:', alert.text)
sleep(2)

# 3> 去除弹窗(同意/移除)
alert.accept()  # 同意
# alert.dismiss()  # 移除

代码示例:

"""
弹出框处理: 系统弹窗处理
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

# 需求:打开注册A.html页面,完成以下操作:
# 1).点击 alert 按钮
# 注意: 凡是通过 JS 实现的系统弹窗, 无法通过鼠标右键检查选项获取元素信息!!!!!!
# driver.find_element(By.ID,'alerta').click()  # 警告框
driver.find_element(By.ID,'confirma').click()  # 确认框
# driver.find_element(By.ID, 'prompta').click()  # 提示框

# 2).关闭警告框
# 1> 切换到弹窗: 只要是系统弹窗, 无论哪一种, 处理方法都是以下的步骤!!!!!!
alert = driver.switch_to.alert

# 2> 获取弹窗信息(可选): 获取弹窗信息必须在处理弹窗操作之前!
print('弹窗信息是:', alert.text)
sleep(2)

# 3> 去除弹窗(同意/移除)
alert.accept()  # 同意
# alert.dismiss()  # 移除

# 3).输入用户名:admin
driver.find_element_by_id('userA').send_keys('admin')

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

注意:凡是通过JS实现的系统弹窗,无法通过鼠标右键检查选顶获取元素信息!!!!!

自定义弹窗

说明:由于自定义弹窗可以通过鼠标右键的检查选项获取元素信息,因此出现自定义弹窗时,直接定义目标元素并操作,移除弹窗即可

滚动条

应用场景:

  1. 在HTML页面中,因前端技术框架的原因,页面元素为动态显示,元素根据滚动条下拉而被加载
  2. 页面注册同意条款,需要滚动条到最底层,才能点击同意

实现方式

# 1. 设置]avaScript脚本控制滚动条
js="window.scrollTo(0,1000)"
(0:左边距:1000:上边距;单位像素)

# 2. selenium调用执行JavaScript脚本的方法
driver.execute_script(js)

说明:selenium中并没有直接提供操作滚动条的方法,但是它提供了可执行JavaScript脚本的方法,所以我们可以通过JavaScript脚本来达到操作滚动条的目的。

代码示例:

"""
滚动条处理
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('https://www.icourse163.org/')
driver.maximize_window()

# 注意: Selenium 框架中没有专门处理滚动条的方法, 需要通过调用 JS 代码实现操作
sleep(2)
# 1> 准备 JS 代码: 1000 只是一个尽可能大的值, 不是准确值
js_down = "window.scrollTo(0,1000)"
# 2> 执行 JS 代码
driver.execute_script(js_down)
sleep(2)

js_down = "window.scrollTo(0,3000)"
driver.execute_script(js_down)
sleep(2)

# 向上: 反向只需要将坐标归零即可
js_up = "window.scrollTo(0,0)"
driver.execute_script(js_up)

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

frame处理

frame: HTML页面中的一种框架, 主要作用是在当前页面中指定区域显示另一面元素;

# 形式一:[了解]
<frameset cols="25%,75%">
    <frame src="frame_01.htm">
    <frame src="frame_02.htm">
</frameset>

# 形式二:
<iframe name="iframe_a" src="frame_a.htm" width="200" height="200"></iframe>
    

应用场景

处于frame中的元素,虽然可以获取元素信息,但是代码执行时无法定位元素,因此需要先执行frame切换,才能进行元素定位操作
 

frame切换方法

浏览器对象.switch_to.frame(frame_reference) -> 切换到指定frame的方法
 #frame_reference: 可以为frame框架的name、id或者定位到的frame元素

浏览器对象.switch_to.default_content() -> 恢复默认页面方法

切换frame操作

以下是在代码示例中使用到的页面源码:

<!DOCTYPE html>
<!-- saved from url=(0077)file:///C:/Users/86178/Desktop/page/%E6%B3%A8%E5%86%8C%E5%AE%9E%E4%BE%8B.html -->
<html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	
	<title>表单综合实例</title>
	<style type="text/css">
		body{background: #F0F0F0}
		form{width: 500px;padding: 10px;margin-top: 20px;margin-left: 30%}
		fieldset{background: #C7C7E2;}
		input{padding: 5px;background: #f8f8f8}
		button{padding: 8px; background: #f8f8f8;border-radius: 5px}
		button:hover{padding: 10px; background: #2F4F4F}
		input:focus{background: #FFC0CB}
		span{display: none}
	</style>
</head>
<body>
<form action="file:///C:/Users/86178/Desktop/page/%E6%B3%A8%E5%86%8C%E5%AE%9E%E4%BE%8B.html">
	<div id="zc">
		<fieldset>
		<legend>注册用户</legend>
			<p id="p1">
				<label for="user">账号</label>
		 		<input type="text" name="user" id="user" placeholder="账号" required="" value="">			
			</p>
	 		<p>
				<label for="password">密码</label>		
				<input type="password" name="password" id="password" placeholder="密码" value="">
	 		</p>
			<p>
				<button type="submit" value="注册">注册</button>
				</p><hr>
			<p></p>
			
			<p><a href="file:///C:/Users/86178/Desktop/page/%E6%B3%A8%E5%86%8CA.html" id="ZCA" target="_blank">注册A页面</a></p>
			<p><a href="file:///C:/Users/86178/Desktop/page/%E6%B3%A8%E5%86%8CB.html" id="ZCB" target="_blank">注册B页面</a></p>
		</fieldset>		
	</div>
</form>
<a href="http://www.sina.com.cn/" target="myframe1">新浪</a>
<a href="http://www.hao123.com/" target="myframe1">hao123</a>
<a href="http://www.taobao.com/" target="myframe2">淘宝</a>
<a href="http://www.baidu.com/" target="myframe2">百度</a><br>
<iframe src="./表单综合实例_files/注册A.html" frameborder="1" height="500" width="48%" name="myframe1" id="idframe1" class="cframe"></iframe>
<iframe src="./表单综合实例_files/注册B.html" frameborder="1" height="500" width="48%" name="myframe2" id="idframe2"></iframe>   

</body></html>

代码示例:

"""
frame 操作: 切换 frame
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///C:/Users/86178/Desktop/%E8%A1%A8%E5%8D%95%E7%BB%BC%E5%90%88%E5%AE%9E%E4%BE%8B.html')

# 案例:打开‘注册实例.html’页面,完成以下操作
# 1). 填写主页面的注册信息
driver.find_element(By.ID, 'user').send_keys('admin')
driver.find_element(By.ID, 'password').send_keys('123456')
sleep(1)
# 2). 填写注册页面A中的注册信息
# 说明: 如果目标元素存在于 frame 中, 就需要先执行切换 frame 操作, 再定位元素
# 切换 frame: 传入的是能够代表 frame 元素唯一性的特征值
driver.switch_to.frame('idframe2')
driver.find_element(By.ID, 'userB').send_keys('admin1')
driver.find_element(By.ID, 'passwordB').send_keys('123456')

# 3). 填写注册页面B中的注册信息

# 4. 展示效果
sleep(1)
# 5. 退出浏览器
driver.quit()

动图演示效果:

注意: 切换回默认页面:如果连续切换多个frame,必须先回到默认页面,才能实现切换下一个frame; frame之间不能直接切换.

多窗口处理

在HTML页面中, 当点击超链接或者按钮的时候, 有的会在新窗口打开页面.

应用场景

想要操作新开页面内的元素时,必须先要完成窗口切换,才能获取目标元素

如何实现多窗口切换

# 在Selenium中封装了获取当前窗口句柄、获取所有窗口句柄和切换到指定句柄窗口的方法:
# 句柄:英文nandle,窗口的唯一识别码I

# 获取当前窗口句柄
浏览器对象.current_window_handle

# 获取所有窗口句柄
浏览器对象.window_handles

# 切换指定句柄窗口
浏览器对象.switch_to.window(handle)

注意:切换窗口操作需要依赖窗口的句柄值才能实现

代码示例:

"""
多窗口操作
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('https://www.baidu.com/')
sleep(1)
# 需求:打开百度首页,完成以下操作
# 1). 点击图片链接
driver.find_element(By.LINK_TEXT, '图片').click()

# 查看当前窗口的句柄值
# 说明: 在浏览器的一个生命周期内(开启到关闭),
# 任意一个窗口都有唯一的一个句柄值, 可以通过句柄值完成窗口切换操作
print('当前句柄值为:', driver.current_window_handle)

# 切换窗口操作
# 1> 获取所含有窗口句柄(包含新窗口)
handles = driver.window_handles
# print(handles)
# print(type(handles))

# 2> 切换窗口: 列表的 -1 索引对应的值, 始终是最新窗口的句柄值
driver.switch_to.window(handles[-1])

# 2). 在打开的页面中,进行查询
driver.find_element(By.CSS_SELECTOR, '[placeholder="拖入图片/输入文字"]').send_keys('小红帽')
driver.find_element(By.CSS_SELECTOR, '[type="submit"]').click()

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

注意: 如果还想重新操作原始页面,务必要先再完成窗口切换.

截图操作

应用场景

在自动化测试中,出现错误时,可以通过截图,辅助判定错误原因

# 截图保存: 默认推荐使用 .png 格式
浏览器对象.get_screenshot_as_file('./info.png')

代码示例:

"""
截图操作
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('https://www.baidu.com/')
sleep(1)
# 需求:打开百度首页,完成以下操作
# 1). 点击图片链接
driver.find_element(By.LINK_TEXT, '图片').click()

# 查看当前窗口的句柄值
# 说明: 在浏览器的一个生命周期内(开启到关闭),
# 任意一个窗口都有唯一的一个句柄值, 可以通过句柄值完成窗口切换操作
print('当前句柄值为:', driver.current_window_handle)

# 切换窗口操作
# 1> 获取所含有窗口句柄(包含新窗口)
handles = driver.window_handles
# print(handles)
# print(type(handles))

# 2> 切换窗口: 列表的 -1 索引对应的值, 始终是最新窗口的句柄值
driver.switch_to.window(handles[-1])

# 2). 在打开的页面中,进行查询
driver.find_element(By.CSS_SELECTOR, '[placeholder="拖入图片/输入文字"]').send_keys('包饺子')
driver.find_element(By.CSS_SELECTOR, '[type="submit"]').click()

sleep(2)
'''
截图保存: 默认推荐使用 .png 格式
driver.get_screenshot_as_file('./info.png')
说明: .jpg 虽然可以使用, 但是会有使用警告
driver.get_screenshot_as_file('./info.jpg')
扩展: 指定图片文件存放路径: 需要先手动创建文件夹!!!!!!
'''
driver.get_screenshot_as_file('./image/info.png')

# 4. 展示效果
sleep(1)
# 5. 退出浏览器
driver.quit()

图片展示:

时间戳防止图片重名被覆盖

因为代码中的图片名称是固定的, 因此会出现重名覆盖问题; 可以使用时间戳防止图片重名被覆盖.

代码示例:

"""
截图操作
"""
# 1. 导入模块
from time import sleep, strftime

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('https://www.baidu.com/')
sleep(1)
# 需求:打开百度首页,完成以下操作
# 1). 点击图片链接
driver.find_element(By.LINK_TEXT, '图片').click()

# 查看当前窗口的句柄值
# 说明: 在浏览器的一个生命周期内(开启到关闭),
# 任意一个窗口都有唯一的一个句柄值, 可以通过句柄值完成窗口切换操作
print('当前句柄值为:', driver.current_window_handle)

# 切换窗口操作
# 1> 获取所含有窗口句柄(包含新窗口)
handles = driver.window_handles
# print(handles)
# print(type(handles))

# 2> 切换窗口: 列表的 -1 索引对应的值, 始终是最新窗口的句柄值
driver.switch_to.window(handles[-1])

# 2). 在打开的页面中,进行查询
driver.find_element(By.CSS_SELECTOR, '[placeholder="拖入图片/输入文字"]').send_keys('湖泊')
driver.find_element(By.CSS_SELECTOR, '[type="submit"]').click()

sleep(2)

'''
扩展: 使用时间戳防止文件重名被覆盖
说明: Windows 系统文件名不支持特殊符号, 尽量只使用下划线, 否则可能无法生存截图文件
'''
now_time = strftime('%Y%m%d_%H%M%S')  # %Y年%m月%d日%H时%M分%S秒
driver.get_screenshot_as_file('./image/info_{}.png'.format(now_time))

# 4. 展示效果
sleep(1)
# 5. 退出浏览器
driver.quit()

图片展示:

验证码

验证码是一种随机生成的信息(数字、字母、汉字、图片、算术题)等为了防止恶意的请求行为,增加应用的安全性。

注意:在自动化测试过程中,必须处理验证码,否则无法继续执行后续测试

面试题: 常见的验证码处理策略

1. 去掉验证码[常用]:测试环境下-采用

2. 设置万能验证码[常用]:生产环境和测试环境下-采用,必须注意保密不要外泄万能验证码

3. 验证码识别技术:通过Python-tesseract来识别图片类型验证码;识别率很难达到100%

4. 记录cookie:通过记录cookie进行跳过登录,不能对登陆本身功能进行测试时使用

cookie绕过原理

客户端登录账号后,将登录状态相关的cookie信息发送给服务器保存,在发送请求,携带的cookie信息如果和服务器保留的一致,则服务器认为客户端为登录状态

应用场景

  1. 实现会话跟踪,记录用户登录状态
  2. 实现记住密码和自动登录的功能
  3. 用户未登录的状态下,记录购物车中的商品

准备工作: 获取已登陆账号的关键cookie字段信息

将BDUSS信息整理成字典形式:

代码示例:

"""
cookie: 绕过登录操作
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('http://www.baidu.com')
driver.maximize_window()  # 窗口最大化

# cookie 绕过登录
# 1> 整理关键 cookie 信息为字典数据
# 注意: 字典数据的 key 必须是 name 和 value!!!!!!
cookie_value = {'name': 'BDUSS',
                'value': 'EgxaVJJV2RBVjl1b3VWNlp-U3phSXc1TUZrUHJ0eEZFVjdrTjh-ZFBDdmJGYnAAAAAAAAAANuIk2fbiJNnW'}
# 2> 调用方法添加 cookie 信息
driver.add_cookie(cookie_value)

# 3> 刷新页面 -> 发送 cookie 信息给服务器进行验证!!!!!!
driver.refresh()

# 注意:
# 1. 本地浏览器中登录的账号, 不能退出, 否则 cookie 信息过期, 需要重新获取
# 2. 不同项目的能够进行登录功能绕过的 cookie 字段信息都不相同, 具体需要询问开发
# 3. 利用 cookie 绕过登录, 则不能对登录功能本身进行测试
# 4. 个别项目如果想要绕过登录, 有可能需要添加多个 cookie 字段

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

以上就是本篇文章的全部内容了, 感谢观看, 记得三连支持一下哦~ 💕

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐