什么是自动化测试
自动化测试,就是把人对软件的测试行为转化为由机器执行测试行为的一种实践,对于最常见的GUI自动化测试来讲,就是由自动化测试模拟之前需要人工在软件界面上的各种操作,并且自动验证其结果是否符合预期。
什么样的项目适合自动化
●需求稳定,不会频繁变更
●研发和维护周期长,需要频繁执行回归测试
●需要在多种平台上重复运行相同测试的场景
●性能、兼容性通过手工测试无法实现,或者手工测试成本太高
●被测软件的开发较为规范,能够保证系统的可测性
●测试人员具备一定的编程能力
自动化测试的类型划分
自动化测试有广义和狭义之分:
●广义:借助工具进行软件测试,都可以称为自动化测试
●狭义:主要指基于UI层的自动化测试
按照测试类型分:
●功能
●性能
●安全
按照测试阶段分:
●基于代码的单元测试
●集成阶段的接口测试
●系统测试阶段的UI自动化
自动化测试用例的设计原则
●自动化测试一般集中在需要重复测试的基本功能、基本业务流以及正向路径操作,不要将复杂的异常测试、复杂业务流程操作等加入到自动化测试用例中
●自动化测试用例尽量保持用例之间的独立性,最好不要形成依赖关系
●自动化测试如果对数据进行了修改,在测试结束后应尽量保持还原,避免对其他用例产生影响
●每个自动化测试用例只能验证一个功能点
webdriver的环境配置
●通过pip install selenium安装最新的selenium。selenium就是web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
●下载对应的Chromedriver或geckodriver,并将driver放到环境变量的路径中
○Chromedriver下载镜像:ChromeDriver Mirror
○geckodriver下载镜像(firefox): geckodriver Mirror
●在pycharm中导入webdriver即可使用:from selenium import webdriver
自动化测试的love四步法
1元素定位 Locate
2元素操作 Operate
3结果断言 Verificate
4异常处理 Except
自动在百度搜索webdriver的例子
Python复制代码
from selenium import webdriver
import time
# 新建一个webdriver实例
driver = webdriver.Chrome()
# 打开百度首页
driver.get("https://www.baidu.com")
# 定位到id为kw的元素并点击它
driver.find_element_by_id('kw').click()
# 定位到id为kw的元素并清空里面的内容
driver.find_element_by_id('kw').clear()
# 定位id为kw的元素并输入webdriver
driver.find_element_by_id('kw').send_keys('webdriver')
# 定位到id为su的元素并点击它
driver.find_element_by_id('su').click()
# 休眠2秒
time.sleep(2)
# 关闭浏览器
driver.close()
页面基本结构
html页面的基本结构
HTML复制代码
html文档头部区域,页面不可见 html文档内容部分,页面可见
常见的页面元素
●容器型元素:div,form,table
●页面元素:a、img、input(button、text、file)、select、CheckBox、radio、textarea、submit
常用的元素定位的方式
●id
●name
●class name
●tag name
●link text
●partial link text
●xpath(万能,可以在Chrome中用$x调试)
●css selector(万能,可以在Chrome中用$$调试)
xpath和css selector为什么是万能的?
1可以通过位置进行定位
2可以通过任意的属性进行定位
Xpath全称指XML path,代表标签的路径
xpath语法
●绝对路径表示法:指从根目录开始的路径表示法,必须根据实际路径逐级表示。如/html/body/form
●相对路径表示法:指从目标对象所在位置开始,找到能够被唯一定位的父元素。根据其父对象进行路径表示的方法。 如://tbody/tr[3]/td[2]/i 或者//tbody/tr[3]//i //表示相对路径,b//a:表示可以是b/a的路径,也可以是b/c/a的路径,也就是,只要在b之后就行
元素定位的常规原则
元素定位方式选择
●页面有id时,优先使用id来定位,其次是name
●Xpath很强悍,但定位性能不是很好,当其他方法不好定位时,可以用
●定位一组相同元素时,可考虑使用tagname或者name
●定位链接时,可考虑linkText或partiallinkText
定位元素的注意事项
●找到带定位元素的唯一属性
●如果该元素没有唯一属性,则先找到能被唯一定位的父元素,再通过父元素,使用xpath或者css selector进行基于父元素的一级一级或者跨层级的定位到元素
●不要使用随机唯一属性定位
●最重要的是多跟研发沟通,尽量把关键元素加上id或者name,并减少不合理的页面元素,例如重复id这样的事情最好不要发生
find_element和find_elements
1find_element 根据指定的方式定位元素,仅仅返回找到的第一个元素,如果没有元素符合,则返回none
2find_elements 根据指定的当时定位元素,以列表形式返回找到的全部元素,如果没有元素符合,则返回空列表
设置等待时间
强制等待/固定等待
●优势:用法非常简单,一般用于项目调试,或者用于等待元素状态、文本发生改变
●劣势:等待时间固定,如果脚本中大量使用会导致脚本运行效率低
Python复制代码
import time # 当前位置等待2秒 time.sleep(2)
隐式等待/全局等待
●只设置一次后,全局有效,在元素没有出现时,最多只能等待指定时间,但如果在等待时间内,什么时候元素出现什么时候停止等待。
●但隐式等待,只能在元素不存在的时候,才会生效,否则,不会产生任何效果,并不会等待元素里面填充内容
Python复制代码
# 最多等待30s,30s内元素存在时,就立即停止等待 driver.implicitly_wait(30)
显示等待
●可针对每一个元素进行单独设置,等待条件更加灵活。
●显示等待和隐式等待如果同时设置,以最长等待时间为准
Python复制代码
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC
常见的EC方法
Python复制代码
# 判断某个元素中的text是否包含了预期的字符串 EC.text_to_be_present_in_element(locator) # 判断某个元素是否可点击,并且是Enable的 EC.element_to_be_clickable(locator) # 判断某个元素是否不可见 EC.invisibility_of_element_located(locator) # 判断某个元素是否可见,可见代表元素非隐藏,并且元素的宽和高不等于0 EC.visibility_of_element_located(locator) # 判断某个元素是否被加载到了dom树里,并不代表该元素一定可见 EC.presence_of_element_located(locator) # 判断当前页面的title是否包含指定字符串 EC.title_contains(locator) # 判断当前页面的title是否精确等于预期 EC.title_is(locator)
例子
Python复制代码
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 显示等待设置最多等待5s的时间,如果隐式等待也设置了值,则取两者中的最大值。
# 显示等待当id为msg中的text文本包含了预期的字符串“出错啦:找不到该用户名...”
WebDriverWait(driver, 5).until(EC.text_to_be_present_in_element(('id', 'msg'), '出错啦:找不到该用户名...'))
智能等待封装todo
验证码的处理
自动化测试某些场景需要填写验证码,增强了安全性,但是对于自动化测试来说,不那么方便
●去掉验证码
●手动输入验证码
●设置万能验证码
webdriver常用api
浏览器常用api
Python复制代码
# 打开浏览器的一个网页
driver.get("https://www.baidu.com")
# 关闭浏览的所有进程
driver.quit()
# 只关闭浏览器的当前窗口
driver.close()
# 设置窗口大小
driver.set_window_size(200, 500)
# 最大化窗口
driver.maximize_window()
# 获取网页源码
print(driver.page_source)
# 获取窗口名称
print(driver.name)
# 刷新页面
driver.refresh()
# 获取网页标题
print(driver.title)
# 获取当前页面的url地址
print(driver.current_url)
# 获取当前页面的截图
path = r'png/a.png'
driver.get_screenshot_as_file(path)
定位元素的api
基本的定位api
Python复制代码
# 通过id查找一个元素
find_element_by_id()
# 通过name查找第一个元素
find_element_by_name()
# 通过name查找所有符合条件的元素,返回的是一个列表
a=find_elements_by_name()
# 可以通过a[下标]来定位到具体的元素。如下
a[1].click()
# 通过classname来定位元素,也是返回一个列表,这个方法只支持单样式,不支持复合样式,多样式
find_elements_by_class_name()
# 查找同类标签的所有元素列表
find_elements_by_tag_name('input')
# 通过完整的超链接文字定位到超链接,并打开超链接
find_element_by_link_text('a超链接的text')
# 通过部分的超链接文字定位到超链接,并打开超链接
find_element_by_partial_link_text('a超链接的text')
xpath的定位api
Python复制代码
# 通过绝对路径的方式定位
driver.find_element_by_xpath('/html/body/form')
# 通过相对路径的方式定位 //表示相对定位
driver.find_element_by_xpath('//tbody/tr[3]/td[2]/i')
# 通过相对路径的方式定位,i在tr[3]的目录里面能唯一确定,具体的层级目录可以使用//相对路径来省略
driver.find_element_by_xpath('//tbody/tr[3]//i ')
# xpath通过属性进行定位,格式为://标签[@属性='属性名'][@属性='属性名']
driver.find_element_by_xpath('//input[@type="file"]')
# xpath模糊定位,//*[contains(text(),"60岁")]表示;查找包含了文本内容为60岁的元素
driver.find_element_by_xpath('//*[contains(text(),"60岁")]')
# //textarea[contains(@placeholder,"yourself")表示;
#查找textarea标签的placeholder属性包含了yourself内容的元素
driver.find_element_by_xpath('//textarea[contains(@placeholder,"yourself")]')
# 可以在浏览器的console调试:
# 取出div标签下的,class属性为login-top的元素的第一个input输入框的元素
#$x("//div[@class='login-top']/input[1]")
css selector定位的api
Python复制代码
# 通过标签名来定位元素
driver.find_elements_by_css_selector('标签名')
# 通过class属性来定位元素
driver.find_element_by_css_selector(".class名")
driver.find_element_by_css_selector(".class名 .class名")
# 通过id属性来进行定位
driver.find_element_by_css_selector("#id名")
# 通过多属性进行定位
driver.find_element_by_css_selector("[属性名=属性值][属性名=属性值]")
# 通过父子关系,用大于符号。能唯一确定的父元素 > 子元素 > 子元素
driver.find_element_by_css_selector("父元素>子元素:nth-child(第几个子元素)>子元素:nth-child(第几个子元素)>子元素")
# 通过孙子关系,用空格,如爷元素 元素。
#下面的例子表示查找tbody下的第三个tr下的i元素。(tr和i之间间隔1个以上的层级关系)
driver.find_element_by_css_selector("tbody > tr:nth-child(3) i")
# 模糊匹配 相当于xpath中的contains。标签[属性*='属性值的部分内容'],这里的*=表示模糊匹配
driver.find_element_by_css_selector("标签[属性*='属性值的部分内容']")
元素操作的api
Python复制代码
# 向文本域或文件上传按钮发送文字内容
.send_keys('输入内容')
# 清除文本框内的内容
.clear()
# 点击按钮
.click()
# 获取节点上的文本信息
.text
# 获取元素属性信息
.get_attribute("属性名")
# 判断元素是否显示出来
.is_displayed()
# 复选框常用操作
# 是否显示
driver.find_element_by_id('kw').is_displayed()
# 是否可用
driver.find_element_by_id('kw').is_enabled()
# 是否选中
driver.find_element_by_id('kw').is_selected()
# 发送复合按键
from selenium.webdriver.common.keys import Keys
# 转大写
driver.find_element_by_id('kw').send_keys(Keys.SHIFT, 'xiaohua')
# 全选
driver.find_element_by_id('kw').send_keys('xiaohua'*50)
driver.find_element_by_id('kw').send_keys(Keys.CONTROL+'a')
# 下拉列表常见操作
from selenium.webdriver.support.ui import Select
# 选中下拉列表的下标为0的元素
Select(driver.find_element_by_id("status")).select_by_index(0)
# 选中下拉列表中value为hz的元素
Select(driver.find_element_by_id("status")).select_by_value('hz')
# 选中下拉列表中,内容为重庆的元素
Select(driver.find_element_by_id("status")).select_by_visible_text("重庆")
frame操作的api
在web应用中,经常会出现frame的嵌套应用。假设页面上有A,B两个frame,B在A内,具体思路:
●使用swtich_to.frame()方法,把当前定位的主体切换到B frame里
●使用swtich_to.default_content() 从B frame切换到A frame
Python复制代码
from selenium import webdriver
# 切换frame
driver.switch_to.frame(driver.find_element_by_id("iframe1"))
# 从frame切换到主文档
driver.switch_to.default_content()
文件上传
Python复制代码
# 只适合type="file"类型的文件上传
driver.find_element_by_id("status").send_keys(r'D:wrok_soft_installchromedrivera.txt')
多窗口切换
有时自动化操作需要在多个窗口来回操作,使用 driver.switch_to.window(窗口的句柄) 来切换窗口。
Python复制代码
# 获得当前的窗口的句柄,可以将当前窗口的句柄保存到变量中,方便以后再想要切换的位置,随时切换到这个窗口 current_window_handle = driver.current_window_handle # 获得当前打开了哪些窗口,返回的是列表,可以通过下标获得指定的窗口句柄。比如:handles[1] handles = driver.window_handles # 切换到窗口current_window_handle driver.switch_to.window(current_window_handle) # 切换到窗口handles[1] driver.switch_to.window(handles[1])
定位悬浮菜单的api
这种就是悬浮菜单
设置
新闻
重庆
直播
贴吧
28*c
学术
地图
视频
更多
hao123
搜索设置
高级搜素
开启预测
隐私设置
展示资讯
关闭撞报
Baidu百度
更换皮肤
百度一下
Python复制代码
from selenium.webdriver.common.action_chains import ActionChains
Python复制代码
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
def xuanfu():
driver.get("http://www.baidu.com")
driver.maximize_window()
item = driver.find_element_by_id("s-usersetting-top")
# 移动到某个元素
ActionChains(driver).move_to_element(item).perform()
driver.find_element_by_link_text("高级搜索").click()
if __name__ == '__main__':
xuanfu()
对于ajax类型的下拉菜单的api
百度搜索提示的效果。
Baidu百度
百度一下
nih
小小字换英
nihss评分
你好
你好生活
你好火焰蓝
你好的英文
你好旧时光
你好周先生
你会长出羽翼拥抱星河万里
Python复制代码
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
def xiala():
driver.get("https://www.baidu.com")
driver.maximize_window()
driver.find_element_by_id("kw").send_keys('n')
time.sleep(2)
menus = driver.find_elements_by_class_name("bdsug-overflow")
for menu in menus:
print(menu.text)
menus[0].click()
if __name__ == '__main__':
xiala()
如果对python自动化测试、web自动化、接口自动化、移动端自动化、大型互联网架构技术、面试经验交流等等感兴趣的老铁们,可以关注我。我会在公众号(程序员阿沐)/群里(810119819)不定期的发放免费的资料链接,这些资料都是从各个技术网站搜集、整理出来的,如果你有好的学习资料可以私聊发我,我会注明出处之后分享给大家。欢迎分享,欢迎评论,欢迎转发。需要资料的同学可以关注我获取资料链接。



