文章目录
自动化测试解决什么问题?
- 解决-回归测试
- 项目在发新版本之后对项目之前的功能进行验证
- 解决-压力测试
- 可以理解多用户同时去操作软件, 统计软件服务器处理多用户请求的能力
- 解决-兼容性测试
- 不同浏览器(IE、 Firefox、 Chrome) 等等
- 提高测试效率,保证产品质量
自动化测试分类
- web-自动化测试
- 移动-自动化测试
- 接口-自动化测试
- 单元测试-自动化测试
什么Web项目适合做自动化测试?
- 需求变动不频繁
- 项目周期长
- 项目需要回归测试
Web自动化测试在什么阶段开始?
- 功能测试完毕
- web自动化测试 属于 黑盒测试(功能测试)
Web自动化测试环境搭建
- python开发环境
- python解释器及开发工具
- pycharm
- 浏览器
- 谷歌
- 火狐—48版本以下,内置驱动
- 安装浏览器驱动
- 对应浏览器的驱动
- 火狐驱动下载地址:https://github.com/mozilla/geckodriver/releases
- 谷歌驱动下载地址:https://sites.google.com/a/chromium.org/chromedriver/downloads
- 各个驱动对应浏览器版本地址:http://www.seleniumhq.org/download/
- 把驱动文件所在目录添加到Path环境变量中,或者直接放到Python安装目录, 将Python添加到Path中
- 通过pip包工具安装selenium包
- 安装
- pip install selenium==版本号(2.48.0) ----》 可以查看具有那些版本
- 卸载
- pip uninstall selenium
- 查看
- pip show selenium
- 查看pip包管理工具安装的插件或者工具
- pip list
- 提示
- 使用pip必须联网
- 默认安装python3.5版本以上工具,自带pip包管理工具,默认会自动安装并且添加path环境变量
- 安装
- pycharm 中 安装 selenium 包
元素定位
-
为什么要使用元素定位?
- 要使用web自动化操作元素,必须首先找到此元素
-
定位方式
1. id
2. name
3. class_name(使用元素的class属性定位)
4. tag_name(标签名称 <标签名 …/>)
5. link_text(定位超连接 a标签)
6. partial_link_text(定位超链接 a标签 模糊)
7. xpath(基于元素路径)
8. css(元素选择器) -
汇总:
1. 基于元素属性特有定位方式(id,name,class_name)
2. 基于元素标签名称定位:tag_name
3. 定位超链接文本(link_text、partial_link_text)
4. 基于元素路径定位(xpath)
5. 基于选择器(css)
id 定位
- 说明:
- 通过元素的id属性定位,id一般情况下在当前页面中是唯一
- 方法
- driver.find_element_by_id(id)
- 提示
- 元素必须要有id属性
# 导包
from selenium import webdriver
from time import sleep
# 获取 浏览器对象
driver = webdriver.Chrome()
# 获取url
url = ""
driver.get(url)
# 查找 用户名元素
username = driver.find_element_by_id("userA")
# 用户名输入 admin send_keys("内容")
username.send_keys("admin")
# 暂停3秒
sleep(3)
# 退出浏览器驱动
driver.quit()
name 定位
- 说明
- 通过元素的name属性定位,name名称一般为重复
- 方法
- driver.find_element_by_name(name)
- 提示
- 元素必须要有name属性
class_name定位
- 说明
- 通过元素的class属性定位,class属性一般有多个值
- 方法
- driver.find_element_by_class_name(class_name)
- 提示
- 元素必须要有class属性
tag_name定位–了解
- 说明
- 是通过元素的标签名称来定位,标签名也就是元素名
- 方法
- driver.find_element_by_tag_name(“标签名”)
- 注意
- 如果页面中存在多个相同标签,默认返回第一个标签元素
link_text
- 说明
- 定位超链接标签
- 方法
- driver.find_element_by_link_text()
- 注意
- link_text:只能使用精准匹配(a标签的全部文本内容)
partial_link_text【推荐】
- 说明
- 定位超链接标签
- 方法
- driver.find_element_by_partial_link_text()
- 注意
- 可以使用精准或模糊匹配,如果使用模糊匹配最好使用能代表唯一的关键词
- 如果有多个值,默认返回第一个值
为什么使用Xpath和css定位?
- id,name,class:依赖于元素这三个对应的属性,如果元素没有以上三个属性,定位方法不能使用。
- link_text,partial_link_text:只适合超链接
- tag_name:只能找页面唯一元素,或者 页面中多个相同元素中的第一个元素
Xpath
-
说明
- 基于元素的路径
-
方法
- driver.find_element_by_xpath()
-
Xpath(Xml Path) 常用的定位策略
- 路径
- 绝对路径
- 语法:以单斜杠开头逐级开始编写,不能跳级。如:/html/body/div/p[1]/input
- 相对路径
- 语法:以双斜杠开头,双斜杠后边跟元素名称,不知元素名称可以使用*代替。
如: //input 或 // *
- 语法:以双斜杠开头,双斜杠后边跟元素名称,不知元素名称可以使用*代替。
- 绝对路径
- 路径结合属性
- 语法:在Xpath中,所有的属性必须使用@符号修饰 如://*[@id=‘id值’]
- 路径结合逻辑(多个属性)
- 语法://*[@id=“id值” and @属性=‘属性值’]
- 路径结合层级
- 语法://*[@id=‘父级id属性值’]/input
- 路径
-
Xpath 扩展
- //*[text()=‘XXX’] # 定位文本值等于XXX的元素
- 提示:一般适合 p标签,a标签
# 定位文本内容为 访问 新浪 网站 的 a标签 //a[text()='访问 新浪 网站']
- //*[contains(@属性,‘xxx’)] # 定位属性包含xxx的元素 【重点】
- 提示:contains为关键字,不可更改。
# 定位id属性包含 A 的超链接元素 //a[contains(@id,'A')]
- //*[starts-with(@属性,‘xxx’)] # 定位属性以xxx开头的元素
- 提示:starts-with为关键字不可更改
# 定位 id属性以 A 开头的超链接元素 //a[starts-with(@id,'A')]
- //*[text()=‘XXX’] # 定位文本值等于XXX的元素
CSS
- css定位就是通过css选择器工具进行定位
- 极力推荐使用,查找元素的效率比xpath高,语法比xpath更简单
- 方法
- driver.find_element_by_css_selector()
- CSS 常用策略
- id 选择器
- 前提:元素是必须有id属性
- 语法:#id 如:#passwordA
- class 选择器
- 前提:元素是必须有class属性
- 语法:.class 如:.telA
- 元素选择器
- 语法:element 如:input
- 属性选择器
- 语法:[属性名=属性值]
- 层级选择器
- 语法:
- p>input
- p input
- 提示:>与空格的区别,大于号必须为子元素,空格则不用
- 语法:
- id 选择器
- CSS 扩展
- [属性^=‘开头的字母’] # 获取指定属性以指定字母开头的元素
# name 属性以 us 开头的 元素 [name^='us']
- [属性$=‘结束的字母’] # 获取指定属性以指定字母结束的元素
# name 属性以 dA 结尾的 元素 [name$='dA']
- [属性*=‘包含的字母’] # 获取指定属性包含指定字母的元素
# class 属性 包含 el 的元素 [class*='el']
8种元素定位的底层实现
- 方式
- driver.find_element(By.xxx, ‘value’)
- 参数说明:
- By.xxx :为By类的类型 如:By.ID
- value: 元素的定位值 如: “userA”
- By类:需要导包
- 位置:from selenium.webdriver.common.by import By
# 使用find_element()定位用户名--> id= 'userA' driver.find_element(By.ID, "userA").send_keys("admin") # 使用find_element()定位密码--> id = 'passwordA' driver.find_element(By.CSS_SELECTOR,"#passwordA").send_keys("123456")
元素操作
- 方法
- send_keys() 输入方法
- click() 点击方法
- clear() 清空
- 提示:
- 在输入方法之前一定要清空操作
浏览器常用操作API
-
方法
- driver.maximize_window() 最大化浏览器
- driver.set_window_size(w, h) 设置浏览器大小 单位像素
- driver.set_window_position(x, y) 设置浏览器位置
- driver.back() 后退操作
- driver.forward() 前进操作
- driver.refresh() # 刷新操作
- driver.close() 关闭当前主窗口(主窗口:默认启动哪个界面,就是主窗口)
- driver.quit() 关闭由driver对象启动的所有窗口
- driver.title 获取当前页面title信息
- drive.current_url 获取当前页面url信息
-
提示
- driver.title 和 driver.current_url 没有括号,应用场景:一般为判断上步操作是否执行成功。
- driver.maximize_window() 一般为前置代码,在获取driver后,直接编写最大化浏览器
- driver.refresh() 应用场景,浏览器cookie缓存,模拟登录,刷新后才能展示效果
- driver.close()与driver.quit()区别:
- close():关闭当前主窗口
- quit():关闭由driver对象启动的所有窗口
- 提示:如果当前只有1个窗口,close与quit没有任何区别。
元素信息操作API
-
方法
- text 获取元素文本 如:driver.定位元素.text
- size 获取元素大小 如:driver.定位元素.size
- get_attribute 获取元素属性值 如:driver.定位元素.get_attribute(“id”)
- is_displayed 判断元素是否可见 如:element.is_displayed()
- is_enabled 判断元素是否可用 如: element.is_enabled()
- is_selected 判断元素是否被选中 如:element.is_selected()
-
提示:
- text和size调用时 无括号
- get_attribute一般应用场景:判断一组元素是否为想要的元素或者判断元素属性值是否正确
- is_displayed、is_enabled、is_selected,在特殊应用场景中使用
鼠标操作
- 鼠标事件对应的方法所在类
- ActionChains类
- 导包 from selenium.webdriver.common.action_chains import ActionChains
- 鼠标事件常用的操作方法
- context_click() 右击
- 应用:context_click(element).perform()
driver = webdriver.Firefox() driver.get(url) # 实例化并获取 ActionChains类 action = ActionChains(driver) # 获取用户名元素 username = driver.find_element_by_css_selector("#userA") # 右击 action.context_click(username).perform()
- double_click() 双击
- 应用:double_click(element).perform()
- drag_and_drop() 拖拽
- 应用:drag_and_drop(source, target).perform
- move_to_element() 悬停
- 应用: move_to_element(element).perform()
- perform() 执行以上事件方法
- context_click() 右击
- 提示:
- selenium框架中虽然提供了,右击鼠标方法,但是没有提供选择右击菜单方法,可以通过发送(send_keys)快捷键的方式解决(个别浏览器适用)
键盘操作
- 键盘对应的方法在Keys类中
- 包:from selenium.webdriver.common.keys import Keys
- 常用的快捷键:
CONTROL:Ctrl键
其他,请参考Keys底层定义的常量 - 应用
- 组合键:element.send_keys(Keys.XXX, ‘a’)
- 单键:element.send_keys(Keys.XXX)
# 定位 用户名
username = driver.find_element_by_css_selector("#userA")
# 输入 admin1
username.send_keys("admin1")
# 删除1
username.send_keys(Keys.BACK_SPACE)
# 全选 admin Ctrl+a
username.send_keys(Keys.CONTROL, "a")
元素等待
- 由于电脑配置或网络原因,在查找元素时,元素代码未在第一时间内被加载出来,而抛出未找到元素异常
- 元素在第一次未找到时,元素等待设置的时长被激活,如果在设置的有效时长内找到元素,继续执行代码,如果超出设置的时长未找到元素,抛出未找到元素异常。
- 元素等待分类
-
隐式等待
- driver.implicitly_wait(30) 一般情况下设置30秒
- 特色:
- 针对所有元素生效。
- 一般情况下为前置必写代码(1.获取浏览器驱动对象;2. 最大化浏览器;3. 设置隐式等待)
-
显示等待
- WebDriverWait(driver,timeout=10, poll_frequency=0.5).until(lambda x:x.find_element_by_id("#user")).send_keys(“admin”)
- 参数:
- timeout: 超时时间
- poll_frequency:访问频率,默认0.5秒找一次元素
- x: x为driver,它是WebDriverWait类将传入的driver赋值给类self._driver,until方法调用了self._driver
- 提示:
- WebDriverWait(driver,timeout=10, poll_frequency=0.5).until(lambda x:x.find_element_by_id("#user"))返回的一个元素
-
显示等待与隐式等待区别:
- 显示等待:针对单个元素生效
- 隐式等待:针对全局元素生效
-
下拉框
- 为什么使用下拉框
- 如果option选项没有value值的化,css定位或其他定位就不太方便。
- 使用Select类
- 操作:
- 导包:from selenium.webdriver.support.select improt Select
- 实例化:s = Select(element)
- 调用方法:s.select_by_index()
- 操作:
- 提供方法
- select_by_index() 通过下标定位
- select_by_value() 通过value值
- select_by_visible_text() 显示文本
# 下标定位
el = driver.find_element_by_css_selector("#selectA")
Select(el).select_by_index(1)
# value值 定位
Select(el).select_by_value("sh")
# 文本定位
Select(el).select_by_visible_text("A上海")
- 注意事项
- 实例化select时,需要的参数为 select标签元素
- 调用Select类下面的方法,是通过索引、value属性值、显示文本去控制,而不需要click事件
弹出框
- 如果页面有弹出框,不处理,接下来的代码将不生效,所以需要对弹出框做处理
- 弹出框分类–以下三种处理方式都一样
- alert 警告框
- confirm 确认框
- prompt 提示框
- 操作步骤
- 切换到对话框
- 方法:driver.switch_to.alert
- 处理对话框
- alert.text 获取文本
- alert.accept() 同意
- alert.dismiss() 取消
- 切换到对话框
# 默认返回的alert对话框对象
at = driver.switch_to.alert
#同意
# at.accept()
# 取消
at.dismiss()
滚动条
- 在web自动化中有些特殊场景,如:滚动条拉倒最底层,指定按钮才可用
- 在selenium中没有直接提供定位滚动条组件方法,但是它提供了执行js语句方法,可以通过js语句来控制滚动条操作
- 操作步骤
-
设置操作滚动条操作语句
- js = “window.scrollTo(0,10000)”
- 0: 左边距 --》水平滚动条
- 10000:上边距 -->垂直滚动条
- js = “window.scrollTo(0,10000)”
-
调用执行js方法,将设置js语句传入方法中
- 方法:driver.execute_script(js)
-
切换frame表单
- 常用的frame表单有两种:frame、iframe
- 切换frame时,可以使用name、id、iframe元素
- 当前主目录内没有iframe表单页面元素信息,不切换,找不到元素
- 方法
- driver.switch_to.frame(“id\name\element”)
- iframe或frame只有在主目录才有相关元素信息,不回到主目录,切换语句会报错
- driver.switch_to.default_content()
多窗口切换
- 页面存在多个窗口式,selenium默认焦点只会在主窗口上所有的元素,不切换切换窗口,无法操作除主窗口以外的窗口内元素
- 切换方法
- driver.current_window_handle 获取当前主窗口句柄
- driver.window_handles 获取当前由driver启动所有窗口句柄
- driver.switch_to.window(handle) 切换窗口
- 切换步骤
- 获取当前窗口句柄
- 点击链接 启动另一个窗口
- 获取当前所有窗口句柄
- 遍历所有窗口句柄
- 判断当前遍历的窗口句柄不等于当前窗口句柄
- 切换窗口操作
截屏
- 应用场景:失败截图,让错误看的更直观
- 方法
- driver.get_screenshot_as_file(imgepath)
- imagepath:为图片要保存的目录地址及文件名称
- 多条用例执行失败,会产生多张图片,可以采用时间戳的形式,进去区分
# strftime:将时间转为字符串函数
driver.get_screenshot_as_file("../image/%s.png" % (time.strftime("%Y_%m_%d %H_%M_%S")))
cookie 解决验证码
- 方法
- driver.get_cookies() 获取所有的cookie
- driver.add_cookies({字典}) 设置cookie
- driver.get_cookie(cookie name) 如: BDUSS
- 案例
- 使用cookie绕过百度登录
- 步骤
- 手动登录百度网站
- 手动获取登录后的cookies ‘BDUSS’
- 使用selenium内的add_cookie(name=‘BDUSS’, value=‘xxxx’)
- 刷新才能看到效果 driver.refresh()
url = "http://www.baidu.com"
driver.get(url)
driver.add_cookie({"name": "BDUSS", "value":"根据实际情况修改"})
driver.refresh()