一、自动化测试
1.1 自动化测试
自动化测试就是把以人为驱动的测试转化成以机器执行的过程。
1.2 什么样的项目适合做自动化测试
1)软件需求变更不频繁
2)项目周期比较长(最低一年以上,最好是自研产品)
3)自动化脚本能够长期重复使用
1.3 自动化脚本一般在什么时候介入
一般在系统测试阶段介入,用于系统的回归测试
1.4 自动化测试流程
可行性分析—>测试需求分析—>制定计划—>自动化用例设计(单独写一份自动化测试,或从功能测试抽取一部分为样本,写一分用例测试)—>脚本开发—>无人值守—>自动生成自动化报告—>脚本维护。
二、常见自动化测试工具或框架
1.selenium
2.Robotframework(RF)
3.Appium
4.QTP(UFT,04后就慢慢淘汰了)
5.其他(Monkey、monkeyrunner、uiautomation等)
三、selenium的功能特点以及组件
1.功能
最新版本3.141.0,基于web自动化的工具,元素定位,窗口跳转,frame处理…
2.特点
开源,免费
支持多语言:python,java,C#,ruby,php等
python:find_element_by_id()
支持多平台:windows,linux,mac
支持分布式运行测试用例:Grid
3.组件
IDE(Firefox插件)
webdriver(核心组件,封装一整套操作浏览器的API)
Grid(实现分布式)
四、python+selenium自动化环境搭建
4.1 下载好指定浏览器的驱动放在python安装的路径下(解压后的文件)
4.2 编写如下脚本
from selenium import webdriver
# 加载谷歌浏览器的驱动
br = webdriver.Chrome()
# 打开百度
br.get('https://www.baidu.com')
五、浏览器的常规操作
from selenium import webdriver
from time import sleep
# 打开浏览器
br = webdriver.Chrome()
# 加载网页
br.get('https://www.baidu.com')
sleep(3)
# 浏览器最大化
br.maximize_window()
sleep(3)
# 设置浏览器大小
br.set_window_size(1200,880)
# 刷新
sleep(3)
br.refresh()
# 返回
br.back()
sleep(3)
# 前进
br.forward()
sleep(3)
# 截图
br.get_screenshot_as_file('e:\\error.png')
# 获取url 一般和断言一起使用
print(br.current_url)
# 获取浏览器的标题
print(br.title)
# 获取网页源码
print(br.page_source)
# 关闭当前窗口
br.close()
# 退出br,关闭所有窗口
br.quit()
六、八大定位元素的方法
F12 右键:检查
前提:唯一
6.1 通过id定位
6.2 通过name定位
6.3 通过class定位
6.4 通过link_text定位
6.5 通过partall_link_text定位
6.6 通过tag_name定位
6.7 通过xpath定位
1)绝对路径(/):/html/body/div/div/div/div/div/form/span/input
2)相对路径(//): //form/span/input
- 通过元素索引定位:(索引从1开始)
6.8 通过css定位
例子:
# 快速导包 alt+enter或ctrl+alt+空格
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
dr = webdriver.Chrome()
dr.get('https://www.baidu.com')
time.sleep(0.5)
# 通过id定位
# dr.find_element_by_id('kw').send_keys('测试苍茫云雾')
# 通过name定位
# dr.find_element_by_name("wd").send_keys('测试苍茫云雾')
# 通过class_name定位
# dr.find_element_by_class_name('s_ipt').send_keys('苍茫云雾')
# 通过link_text(超链接,针对a标签)定位
# dr.find_element_by_link_text('新闻').click()
# 通过partail_link_text定位(针对a标签)
# dr.find_element_by_partial_link_text('新').click()
# 通过标签名定位,一般不用。很难唯一
# print(dr.find_element_by_tag_name('form').get_attribute('action'))
# 通过xpath定位。完成复杂的定位(xpath,css)
# 绝对路径 以/开头
# dr.find_element_by_xpath('/html/body/div/div/div/div/div/form/span/input').send_keys('苏炳添')
# 相对路径 以//开头
# dr.find_element_by_xpath('//form/span[1]/input').send_keys('苏炳添')
# 索引定位
# dr.find_element_by_xpath('//form/span[2]/input').click()
# 属性定位
# dr.find_element_by_xpath('//input[@autocomplete="off"]').send_keys('苏炳添')
# dr.find_element_by_xpath('//input[@autocomplete="off" and @name="wd"]').send_keys('苏炳添',Keys.ENTER)
# 部分的属性值
# dr.find_element_by_xpath('//input[starts-with(@autocomplete,"of")]').send_keys('苍茫云雾',Keys.ENTER)
# dr.find_element_by_xpath('//input[contains(@class,"pt")]').send_keys('苍茫云雾',Keys.ENTER)
# 通过文本定位
# dr.find_element_by_xpath('//a[text()="新闻"]').click()
# 各种xpath组合
# dr.find_element_by_xpath('//a[contains(text(),"新")]').click()
# dr.find_element_by_xpath('//form[@id="form"]/span[1]/input').send_keys('苍茫云雾',Keys.ENTER)
# 通配符* 代表所有
# 通过css定位(html,javaScript,css,h5+css3),通过.找class,通过#找id
'''
1. 绝对路径
2. 相对路径(通过class和id定位)
3. 通过属性定位
4. 通过部分属性值
5. 通过查询子元素
6. 查找兄弟元素
'''
# 1.绝对路径(以空格隔开元素或>)
# dr.find_element_by_css_selector('html body div div div div div form span input').send_keys('苏炳添',Keys.ENTER)
# dr.find_element_by_css_selector('html>body>div>div>div>div>div>form>span>input').send_keys('苏炳添',Keys.ENTER)
# dr.find_element_by_css_selector('html body div.wrapper_new div#head div.head_wrapper.s-isindex-wrap.nologin div div form span input').send_keys('苏炳添',Keys.ENTER)
# 2.相对路径(通过class和id定位)
# dr.find_element_by_css_selector('#kw').send_keys('苏炳添',Keys.ENTER)
# dr.find_element_by_css_selector('input#kw').send_keys('苏炳添',Keys.ENTER)
# class
# dr.find_element_by_css_selector('input.s_ipt').send_keys('苏炳添',Keys.ENTER)
# 3.属性值定位
# dr.find_element_by_css_selector('input[autocomplete="off"]').send_keys('苏炳添',Keys.ENTER)
# dr.find_element_by_css_selector('input[@autocomplete="off"][@name="wd"]').send_keys('苏炳添',Keys.ENTER)
# 4.部分属性的值 ^表示结尾,$表示开头 *包含
# dr.find_element_by_css_selector('input[autocomplete^="of"]').send_keys('苏炳添',Keys.ENTER)
# dr.find_element_by_css_selector('input[autocomplete$="of"]').send_keys('苏炳添',Keys.ENTER)
# dr.find_element_by_css_selector('input[autocomplete*="of"]').send_keys('苏炳添',Keys.ENTER)
# 5.通过查询子元素 通过空格和大于号查找子元素(只能一级一级找)
# dr.find_element_by_css_selector('div#s-top-left a:nth-child(3)').click()
# 6.查找兄弟元素
dr.find_element_by_css_selector('div#s-top-left a +a').click()
七、自动化框架中封装定位
from selenium.webdriver.common.by import By
dr.find_element(By.ID,"kw").send_keys('苍茫云雾')
一、常见的一些操作元素的方法和属性
import time
from selenium import webdriver
dr = webdriver.Chrome()
dr.get("http://47.107.116.139/shopnc/admin/index.php?act=login&op=login")
time.sleep(2)
dr.find_element_by_id('user_name').send_keys('默认值')
time.sleep(2)
# 清空输入框
dr.find_element_by_id('user_name').clear()
# 输入账号
dr.find_element_by_id('user_name').send_keys('admin')
time.sleep(2)
# 输入密码
dr.find_element_by_id('password').send_keys('admin123')
print(dr.find_element_by_id('password').get_attribute('name'))
time.sleep(6)
# dr.find_element_by_id('//input[@value="登录"]').click()
dr.find_element_by_id('form_login').submit()
'''
# 当网页有元素(有属性:disable)不可以用时,可以使用js执行元素的属性,然后再使用元素
js = "document.getElementById('username').removeAttribute('disabled')"
dr.execute_script(js)
'''
'''
# 当网页有元素被隐藏不可见时,可以执行js,然后就可以操作了
js = "document.getElementById('username').style.display=''"
dr.execute_script(js)
'''
'''
# 判断下拉框中某一项是否被选中
print(dr.find_element_by_xpath('//select/option(2)').is_selected())
# 判断下拉框是否可用
dr.find_element_by_xpath('//select/option(2)').is_enabled()
# 判断下拉框是否隐藏
dr.find_element_by_id('//select/option(2)').is_displayed()
'''
二、鼠标和键盘的操作
使用ActionCharins(动作链),通过perform()来执行。
2.1 鼠标的相关操作
左键单击 (click或ActionChains(dr).click(ele2).perform()
dr = webdriver.Chrome()
dr.get('https://www.baidu.com')
ele = dr.find_element_by_id('kw')
ele.send_keys('苍茫云雾')
ele2 = dr.find_element_by_id('su')
# 单击
ActionChains(dr).click(ele2).perform()
右键单击
ActionChains(dr).context_click(ele).perform()
双击
# 双击
ActionChains(dr).double_click(ele).perform()
长按
ActionChains(dr).click_and_hold(ele).perform()
悬浮
# 悬浮
xinwen = dr.find_element_by_link_text('新闻')
ActionChains(dr).move_to_element(xinwen).perform()
# # 悬浮“新闻”的坐标
ActionChains(dr).move_by_offset(xinwen.location['x'],xinwen.location['y']).perform()
三、常见自动化场景操作
3.1 验证码cookie绕过
1)让开发屏蔽验证码
2)在后台设置万能码
3)通过cookie绕过验证码登录
浏览器
什么是cookie?
它是保存在客户端的一个字典格式的字符串
cookie:cookie,seesion,token的区别?
什么是session?
session是保存在服务器的数据,并且session可以通过cookie来传递。名字一般是xxSessionID
1、知道正确的用户和密码
2、获取cookie字典(登录成功的)
接口,APP
什么是token?
token是一个鉴权码:通过登录接口传递。
3.2 frame/iframe框架处理
dr.switch_to.frame('workspace')
# 跳出框架
# dr.switch_to.default_content()
3.3 下拉框处理
# 下拉框
sel = Select(dr.find_element(By.NAME,'search_brand_id'))
# 获取下拉框值的方式1:通过value选中下拉框中的值
sel.select_by_value('80')
# 获取下拉框值的方式2:通过索引获取值,索引从0开始
sel.select_by_index('0')
dr.find_element(By.ID,'ncsubmit').click()
3.4 文件上传处理
# 文件上传处理
dr.find_element(By.ID, '_pic').send_keys('c:/users/Administrator/Desktop/b.jpg')
sleep(2)
dr.find_element('pic_submit').click()
sleep(2)
dr.find_element(By.ID, 'submit').click()
3.5 定位一组元素
# 3、定位一组元素
checkboxList = dr.find_elements(By.NAME,'id[]')
checkboxList[0].click()
3.6 浏览器多窗口处理
# 5、浏览器多窗口处理
# 获取当前窗口的句柄
currentHandle = dr.current_window_handle
# 获取所有窗口的句柄
allHandle = dr.window_handles
for i in allHandle:
if i!= currentHandle:
# 通过窗口的句柄定位到新的窗口
dr.switch_to.window(i)
# 断言,看网页标题是否一致
self.assertEqual(dr.title,"网页标题")
sleep(10)
# 返回旧窗口
dr.switch_to.window(currentHandle)
3.7 滚动条处理
# 滚动条的处理
def test2_gundongtiao(self):
global dr
dr = webdriver.Chrome()
dr.get('http://baidu.com')
dr.implicitly_wait(10)
js = 'document.documentElement.scrollTop=1000'
dr.execute_script(js)