UI
:
User Interface(
⽤户接⼝
-
⽤户界⾯
)
,主要包括:
app
、
web
ui
⾃动化测试:使⽤⼯具或代码执⾏⽤例的过程
什么样的项⽬适合做⾃动化:
1、需要回归测试项⽬(甲⽅⾃营项⽬、⾦融、电商)
2、需求变动不频繁:稳定的模块
3、项⽬周期⻓的项⽬:(甲⽅⾃营项⽬、6个⽉以上的外包)
⾃动化测试⽬的:提⾼测试效率
⾃动化测试⼯具及环境:
⼯具
QTP:商业、收费、⽀持
UI
robot Framework:
python
扩展库、使⽤封装好的关键字驱动、半代码⽔平、 ⽀持UI selenium:开源、免费、主流 ⽀持
UI(推荐)
selenium介绍:
提示:
1、selenium-grid可以做分布式(批量在不同平台中运⾏⽤例),⾃动化⽤例较多时、或测试不
同浏览器在不同平台运⾏时可以使⽤。
2、对⻚⾯元素实施⾃动化测试,主要使⽤:webdriver (我觉得这个最多使用的,可能是接触不深)
selenium-webdriver环境搭建
所需环境:
pthon
解释器
+pycharm+selenium+
浏览器
+
浏览器驱动
selenium安装命令
pip install selenium
(特地去查了一 下安装 pip 自从Python 3.4版本开始,pip已经被内置在Python中,所以无需再次安装。)
浏览器驱动(这里我是使用的edge浏览器,所以根据需求自己安装相应的驱动,可以去查一下)
chrome:
http://npm.taobao.org/mirrors/chromedriver/
提示:浏览器驱动⼤版本必须和浏览器版本⼀致。
windows:
1、解压下载的驱动,获取到chromedriver.exe
2、将chromedriver.exe复制到python.exe所在⽬录即可(避免再次将chromedrver.exe
添加path变量)
mac:
1、解压下载的驱动,获取到chromedriver
2、将chromedriver复制到/usr/local/bin⽬录即可。
元素定位:
为什么要学习
xpath
和
css
?
1、如果标签没有(id\name\class)3个属性,也不是链接标签,只能使⽤tag_name定位,⽐较麻
烦。
2、⽅便在⼯作⽤中查找元素,使⽤xpath和css⽐较⽅便(⽀持任意属性、层级)来找元素
Xpath:使⽤标签路径来定位
绝对路径:从根⽬录开始,逐级查找标签。/html/body/form/div/fieldset/center/p[1]/input
相对路径:从任意路径开始,查找标签。//center/p[1]/input
# 绝对路径
#el =driver.find_element_by_xpath("/html/body/form/div/fieldset/center/p[1]/input
")
el=driver.find_element(By.XPATH,'/html/body/form/div/fieldset/center/p[1]/input')
el.send_keys("admin")
sleep(2)
# 清除内容
el.clear()
# 相对路径
driver.find_element(By.XPATH,"//p[1]/input").send_keys("123")
属性
单属性:
//*[@
属性名
='
属性值
']
多属性:
//*[@
属性名
='
属性值
' and @
属性名
='
属性值
']
提示:可以使⽤任何属性。
层级与属性
说明:
如果元素现有的属性不能唯⼀匹配,需要结合层级使⽤
语法:
//⽗标签
/
⼦标签
必须为直属⼦级
//⽗标签
[@
属性
='
值
']//
后代标签
⽗和后代之间可以跨越元素
可以扩展:
根据显示⽂本定位:
//*[text()='
⽂本值
']
属性值模糊匹配:
//*[contains(@
属性名
,'
属性部分值
')]
from time import sleep
from selenium import webdriver
# 1、获取浏览器
driver = webdriver.Chrome()
# 2、打开url
driver.get("file:///E:/%E6%B5%8B%E8%AF%95%E8%B5%84%E6%96%99%E3%80%90%E5%AF%86%E7%A0%81%E6%98%AF%EF%BC%9A666java.com%E3%80%91/%E6%B5%8B%E8%AF%95%E8%B5%84%E6%96%99/09UI/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
# 3、查找操作元素
# 点击登录链接 ⽂本
driver.find_element(By.XPATH,"//*[text()='登录']").click()
# 输⼊⽤户名 属性
driver.find_element(By.XPATH,"//*[@placeholder='⼿机号/邮箱']").send_keys("13600001111")
# 密码 包含
driver.find_element(By.XPATH,"//*[contains(@placeholder,'密')]").send_keys("123456")
# 验证码 多属性
driver.find_element(By.XPATH,"//*[@placeholder='验证码' and @name='verify_code']").send_keys("8888")
# 登录按钮 层级
driver.find_element(By.XPATH,"//*[@class='login_bnt']/a").click()
# 4、关闭浏览器
sleep(3)
driver.quit()
css选择器:html
查找元素的⼯具
id
选择器
语法:
#id
属性值
前置:
标签必须
id
属性
类选择器
语法:
.class
属性值
前置:
标签必须
class
属性
标签选择器
语法:
标签名
提示:
注意标签是否在⻚⾯中唯⼀,否则返回单个或所有
属性选择器
语法:
[
属性名
='
属性值
']
说明:
标签任意属性都可以
⽤户名 id选择->#id属性值
driver.find_element_by_css_selector("#userA").send_keys("admin")
# 密码 属性选择器->[属性名='属性值']
driver.find_element_by_css_selector("[name='passwordA']").send_keys("123456")
# 电话 类选择器->.class属性值
driver.find_element_by_css_selector(".telA").send_keys("18600000000")
# 确定 标签选择器-标签名
sleep(2)
driver.find_element_by_css_selector("button").click()
层级选择器
⽗⼦关系:
选择器
>
选择器
如:
#p1>input
后代关系:
选择器 选择器
如:
#p1 input
提示:
选择器使⽤任何⼀种
css
选择器(
id
选择器、类选择器、属性选择器、标签选
择器)都可以
find_element:
说明:
⼋种元素定位⽅法底层使⽤的查找元素⽅法都是
find_element,
通过
By
不同的值区
分定位⽅式
⽬的:
后期为了查找元素⽅法的封装
#By的导入 可以使用alt+enter键,就会导入相应的包
from selenium.webdriver.common.by import By
driver.find_element(By.ID,"userA").send_keys("admin")
driver.find_element(By.NAME,"passwordA").send_keys("123456")
driver.find_element(By.CLASS_NAME,"telA").send_keys("18600000000")
sleep(2)
driver.find_element(By.TAG_NAME,"button").click()
结论: 1、⾸推css定位,原因执⾏速度快。
(我个人最喜欢这个哈,最常用的上面的一行的方式)
①如果有ID属性,使⽤#id
②没有id属性,使⽤其他有的属性(能代表唯⼀的属性)
③如果属性都带不了唯⼀,使⽤层级
2、如果css解决不了,使⽤xpath。
元素操作:
元素
=driver.find_element()
点击:元素
.click()
输⼊:元素
.send_keys(
内容
)
清空:元素
.clear()
获取元素信息:
获取⼤⼩:
元素
.size
获取⽂本:
元素
.text
获取属性:
元素
.get_attribute('
属性名
')
元素是否可⻅:
元素
.is_displayed()
元素是否可⽤:
元素
.is_enabled()
元素是否选中:
元素
.is_selected()
# 获取⼤⼩ 元素.size
user = driver.find_element(By.CSS_SELECTOR,"#userA").size
print("⽤户名输⼊框的⼤⼩:",user)
# 获取内容 元素.text
a_text = driver.find_element(By.TAG_NAME,"a").text
print("第⼀个a标签的⽂本:",a_text)
# 获取属性 超连接地址
a_href = driver.find_element(By.TAG_NAME,"a").get_attribute("href")
print("第⼀个a标签的链接:",a_href)
# 判断span标签是否可⻅ 元素.is_displayed
span = driver.find_element(By.TAG_NAME,"span").is_displayed()
print("span是否可⻅:",span)
# 判断取消按钮是否可⽤ is_enabled
btn_is_enabled = driver.find_element(By.CSS_SELECTOR,"#cancelA").is_enabled()
print("取消按钮是否可⽤:",btn_is_enabled)
# 旅游是否选中 is_selected
is_selected = driver.find_element(By.CSS_SELECTOR,"#lyA").is_selected()
print("旅游是否被选中:",is_selected)
api操作:
需求:
打开注册A.html页面,完成以下操作
1).最大化窗口
2).暂停3s,设置窗口宽度:500px,高度:700px
3).暂停3s,设置窗口位置:x=0px,y=500px
4).暂停3s,点击界面 百度 超链接
5).暂停3s,返回注册A页面
6).暂停3s,前进到百度页面
7).暂停3s,刷新百度页面
8).暂停3s,关闭浏览器
# 最⼤化浏览器
driver.maximize_window()
sleep(3)
# 设置窗⼝⼤⼩
driver.set_window_size(500,700)
sleep(3)
driver.set_window_position(0,500)
sleep(3)
# 点击新浪
driver.find_element_by_partial_link_text("新浪").click()
sleep(3)
# 后退
driver.back()
sleep(3)
# 前进
driver.forward()
sleep(3)
driver.refresh()
sleep(3)
driver.quit()
1、close关闭当前焦点所在窗⼝ driver.close()
2、quit关闭的是浏览器 driver.quit()
3、获取标题
driver.title
4、获取网页地址 driver.current_url
下拉框:
方式一:(这种更加简洁,推荐哈)
# 点击⼴州
driver.find_element(By.CSS_SELECTOR, "[value='gz']").click()
sleep(2)
driver.find_element(By.CSS_SELECTOR, "[value='sh']").click()
sleep(2)
driver.find_element(By.CSS_SELECTOR, "[value='bj']").click()
方式二:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
# 使⽤Select类来实现
# 1、定位下拉框元素 select
el = driver.find_element(By.CSS_SELECTOR,"#selectA")
# 2、实例化Select对象
select = Select(el)
# 3、使⽤下标定位⼴州
select.select_by_index(2)
sleep(2)
# 使⽤value定位上海
select.select_by_value("sh")
# 使⽤⽂本定位 北京
sleep(2)
select.select_by_visible_text("A北京")
弹框:
当界面存在弹出框时,必须先处理掉弹出框才能继续其它操作!
1、获取弹窗对象
2、点⽤同意或取消⽅法
# 点击弹窗
driver.find_element(By.ID,"alerta").click()
sleep(2)
# 获取弹窗对象
el = driver.switch_to.alert
# 处理弹窗 同意/取消
# el.dismiss() # 取消
# print("弹出⽂本:",el.text)
el.accept() # 同意
sleep(2)
# 输⼊⽤户名
driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin")
滚动条:
有些⻚⾯场景,必须滚动条拉倒最底下才做某事
如:注册⻚⾯,阅读完需求,协议才能勾选,此时就必须拖动滚动条。
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("file:///E:/%E6%B5%8B%E8%AF%95%E8%B5%84%E6%96%99%E3%80%90%E5%AF%86%E7%A0%81%E6%98%AF%EF%BC%9A666java.com%E3%80%91/%E6%B5%8B%E8%AF%95%E8%B5%84%E6%96%99/09UI/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA%E7%B4%AB%E8%89%B2.html")
# driver.set_window_size(100,500)
# sleep(2)
# js -> 向下滑动10000像素
# js_down = "window.scrollTo(0,10000)"
# 动态执⾏滑倒底部 向下滑动滚动条⾼度
# js(0,10000) 第⼀个0为⽔平滚动条
js_down = "window.scrollTo(0,document.body.scrollHeight)"
# 执⾏js⽅法
driver.execute_script(js_down)
sleep(2)
# js—> 向上
js_top = "window.scrollTo(0,0)"
driver.execute_script(js_top)
鼠标操作:
from selenium.webdriver import ActionChains
# 获取ActionChains对象
action = ActionChains(driver)
# 查找注册按钮
el = driver.find_element(By.CSS_SELECTOR,"button")
sleep(2)
# 调⽤悬停⽅法
action.move_to_element(el).perform()
# username = driver.find_element(By.CSS_SELECTOR,"#userA")
# # 右击
# action.context_click(username).perform()
username = driver.find_element(By.CSS_SELECTOR,"#userA")
username.send_keys("admin")
sleep(3)
# 双击
action.double_click(username).perform()
# 拖拽
action = ActionChains(driver)
div1 = driver.find_element(By.CSS_SELECTOR, "#div1")
div2 = driver.find_element(By.CSS_SELECTOR, "#div2")
action.drag_and_drop(div1, div2).perform()
等待:
代码执⾏过程中,第⼀次未找到元素,先不抛出异常。激活等待时间,在等待过程中如果找到元素
就执⾏。
类型:
1、隐式等待
2、显示等待
3、强制等待 -->time.seep(秒)
隐式元素等待
说明:
针对全部元素⽣效
⽅法:
driver.implicitly_wait(
秒
)
定位元素时,如果能定位到元素则直接返回该元素,不触发等待;
如果不能定位到该元素,则间隔一段时间后再去定位元素;
如果在达到最大时长时还没有找到指定元素,则抛出元素不存在的异常NoSuchElementException。
显示等待
说明:
针对单个元素⽣效,可以修改查找频率和超时时间。
定位元素时,如果能定位到元素则直接返回该元素,不触发等待;
如果不能定位到该元素,则间隔一段时间后再去定位元素;
如果在达到最大时长时还没有找到指定元素,则抛出超时异常
TimeoutException
特点:
查找并返回元素
from selenium.webdriver.support.wait import WebDriverWait
# 2、显示等待 -> 返回查找到的元素
el = WebDriverWait(driver,10,0.5).until(lambda x:
x.find_element(By.CSS_SELECTOR,"#userAA"))
el.send_keys("admin")
强制等待
语法:
sleep(10)
提示:
执⾏到这句必须等待
10
秒,不灵活。
frame标签:在页面中加载另一个页面。
焦点默认在启动⻚⾯,如果不出处理
iframe
,⽆法操作
iframe
嵌⼊的⻚⾯元素。
步骤:
1、切换到iframe driver.switch_to.frame(iframe元素)
2、操作元素
3、回到默认⻚⾯ driver.switch_to.default_content()
# 获取注册A iframe元素
A = driver.find_element(By.CSS_SELECTOR, "#idframe1")
# 1、切换到A
driver.switch_to.frame(A)
# 2、注册A操作
driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin")
# 3、回到默认⽬录 注册时例.html
driver.switch_to.default_content()
# 4、获取注册B iframe元素
B = driver.find_element(By.CSS_SELECTOR, "#idframe2")
# 5、切换到B
driver.switch_to.frame(B)
# 6、注册B操作
driver.find_element(By.CSS_SELECTOR,"#userB").send_keys("admin")
多窗口切换:
selenium默认启动时,所有的焦点在启动窗⼝,那么意味着⽆法操作其他窗⼝的标签。
步骤:
1、获取窗⼝句柄 driver.window_handles
2、使⽤句柄切换窗⼝ driver.switch_to.widnow(handle)
句柄:窗⼝的唯⼀标识符。
"""
需求:
1、打开注册示例⻚⾯
2、点击注册A⽹⻚链接
3、填写注册A⽹⻚内容
"""
print("操作之前所有窗⼝的句柄:", driver.window_handles)
driver.find_element(By.LINK_TEXT, "注册A⽹⻚").click()
handles = driver.window_handles
print("操作之后所有窗⼝的句柄:", handles)
# 重点:切换窗⼝
driver.switch_to.window(handles[1])
# 填写注册A⽹⻚ ⽤户名
driver.find_element(By.CSS_SELECTOR, "#userA").send_keys("admin")
多窗口之间切换工具封装:
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
driver= webdriver.Edge()
driver.implicitly_wait(10)
driver.get("file:///E:/%E6%B5%8B%E8%AF%95%E8%B5%84%E6%96%99%E3%80%90%E5%AF%86%E7%A0%81%E6%98%AF%EF%BC%9A666java.com%E3%80%91/%E6%B5%8B%E8%AF%95%E8%B5%84%E6%96%99/09UI/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/Register.html")
def switch_window(title):
# 1、获取所有窗⼝句柄
handles=driver.window_handles
# 2、遍历句柄进⾏切换
for handle in handles:
driver.switch_to.window(handle)
if driver.title==title:
return "已找到{}窗⼝,".format(title)
title_A="注册A"
title_B="注册B"
driver.find_element(By.LINK_TEXT,"注册A网页").click()
driver.find_element(By.LINK_TEXT,"注册B网页").click()
switch_window(title_A)
driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin")
switch_window(title_B)
driver.find_element(By.CSS_SELECTOR,"#userB").send_keys("admin")
sleep(13)
driver.quit()
如果定位不到元素的时候,咋办,可以分析什么原因造成的?
检查元素定位代码是否正确,是否匹配到唯一元素,是否有做元素等待,是否需要鼠标悬浮,元素是否在新窗口,是否存在于iframe标签中
截图:
当前ui⻚⾯,截图保存;出错后,⽅便查看直观错误原因;
driver.get_screenshot_as_file("xxx.png")
driver.get_screenshot_as_file("error_{}.png".format(time.strftime("%Y_%m_%d
%H_%M_%S")))
验证码:
处理方式:
1、去除验证码
2、使⽤万能验证码
3、使⽤图⽚识别技术(识别效率低)
4、使⽤cookie:
由服务器⽣成,存储在客户端的登录凭证
1、获取cookie # 获取所有driver.get_cookies()
2、添加cookie # driver.add_cookie(data)
driver.get("https:www.baidu.com")
data = {
"name":"BDUSS",
"value":"xxxxxxxxx"
}
driver.add_cookie(data)
暂时就到这,后面再补