Python自动化测试笔记

自动化入门

软件测试六大模块

  1. 功能性测试

  2. 可用性测试(用户体验)
    手机应用程序运行太慢
    删除数据无二次确认
    页面布局不美观
    网站经常出现弹窗广告
    页面字体颜色刺眼,字体太小
    网页上的超链接显示不明显

  3. 性能测试(高并发)
    网页长时间打不开,反应很慢
    应用程序运行太久占用内存很大
    系统运行不流畅
    高并发时系统崩溃

  4. 安全性测试(系统漏洞)
    经常接收到骚扰电话
    WIFI万能钥匙
    银行账户余额被恶意转走
    网站首页被恶意篡改
    手机上联系人信息被窃取
    网站被大量用户非法攻击

  5. 兼容性测试(客户端兼容性)技术性要求不高,操作繁琐
    某网页IE和firefox上显示效果不一样
    中国插座在欧美无法使用
    APP应用程序在某台设备上无法安装
    某应用程序在win10上经常卡顿

  6. 可靠性测试**(系统是否稳定,容错性,捕获异常的能力)
    测试流程——计划、分析、设计、实施(执行)、报告总结

自动化测试价值

概念:自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程

自动化测试的优势
提高测试执行效率,节约时间成本
解放人力去做更加重要的工作
可重复利用,减少对人的依赖
提高用户满意度
提升软件团队的水平
可大幅减少兼容性测试的工作量
有些测试工作必须依靠自动化来完成

自动化测试的不足
开发自动化测试脚本需要花费较长的周期
随产品的不断迭代,自动化测试脚本也将不断迭代,时间成本高
不同的项目间自动化测试脚本的重用度低(接口测试)
对于短期项目产品实施自动化价值不高
自动化测试无法代替手工测试找到产品的BUG
自动化测试开发过程对软件测试团队的技术有较高要求

测试的核心价值在于测试的分析与设计,手工自动化只是执行手段

自动化测试可行性

产品架构与业务可行性
单机应用程序,重点考虑界面级自动化测试
分布式应用系统,重点考虑接口级与界面级结合的自动化测试
手机APP应用,重点考虑接口级与界面级结合的自动化测试,重点关注兼容性
复杂业务场景,重点考虑接口级或代码级自动化测试,界面级测试可不作重点关注。且摘取使用频率最高的模块进行测试
简单业务场景,可考虑不进行或只进行界面级自动化测试

测试技术实现可行性

自动化测试可应用于界面级、接口级、代码级
不同的被测产品应根据不同的情况进行有针对性的技术选择
自动化测试技术并不难,重点是测试方案的定制
通用优先技术选择顺序,接口级>界面级>代码级
自动化测试工具选择面广,但没有一款工具可以完全满足企业需求,所以对自动化测试技术底层实现原理的理解和应用要优先于对工具的考虑选型

自动化测试更多用于回归测试或兼容测试,不能以寻找bug为目的
80%的企业自动化测试实施工作无法坚持,效果不理想,主要针对于页面,页面设计改动过于频繁。

什么样的项目适合做自动化测试
满足任一项就可以做

  1. 需求变动不频繁的(理想)
  2. 项目周期较长
  3. 自动化脚本可以重复使用

自动化测试使用场景:

  • 适用于兼容性测试
  • 适用于回归测试
  • 在迭代项目中对老功能使用自动化
  • 适用于冒烟测试(理论)

自动化测试常用工具

代码级自动化常用测试工具

xUnit;JUnit;CppUnit;NUnit;PyUnit…
XMock;JMock;NMock;-------桩
桩:假设与其交互部分已经完成
功能:断言、参数化、测试用例管理、Mock-桩,TDD–测试驱动开发,BDD–用户驱动开发

接口级自动化常用测试工具

LoadRunner(惠普、收费) —— 支持全协议 ,重点支持HTTP
SOAPUI —— 支持webservice协议SOAP
webLoad —— 支持HTTP协议
RPT(IBM)——重点支持HTTP和TCP/UDP协议
JMeter(Apache)——支持HTTP和JMS协议
浏览器插件postman,RESTClient——支持HTTP

界面级自动化常用测试工具

selenium:支持web应用,多语言多浏览器
APPium:Android,IOS移动应用
QTP/UFT:支持Windows,web,java,.NET应用程序
RFT:支持Windows,web,java,.NET应用程序
robot framework:关键字驱动自动化测试工具

主流测试工具汇总

web自动化测试:selenium、robot、framework
App端自动化测试:Appium、Monkeyrunner、UIautomation
PC客户端(win32)自动化测试:QTP
接口自动化测试:Jmeter、postman、httpUnit、RESTClient
云测试平台:Testin Testbird
性能测试:Jmeter、LoadRunner

主流自动化测试框架有哪些:

  1. web网页自动化:selenium + 编程语言 + 测试框架
  2. app自动化:appium + 编程语言 + 测试框架
  3. 接口自动化 :编程语言 + http库 + 测试框架
  4. web网页/ app/接口自动化 :RobotFramework

web自动化测试

1.web网页
2.在游览器中访问网页
3.通过浏览器与web网页进行交互(操作页面,输入输出)
目标:让代码代替人工完成与互联网浏览器的交互

web自动化-环境安装

  1. 安装浏览器-Google,firefox,IE…
  2. 安装浏览器驱动-chromedriver.exe、geckodriver.exeps
    注意:浏览器与该浏览器驱动的版本必须匹配一致
    注意:浏览器必须自己完成安装,不能从其他地方获取文件夹或链接,虽然同样可以打开浏览器,但在程序中与浏览器驱动配合时会报错!!!!!!!!
    注意:将下载好的浏览器驱动解压后,将xx.exe文件放置在python安装路径的根目录下
  3. 安装selenium框架(提供了与web网页交互的一组组件)Selenium WebDriver
    框架:提供了完成某项任务的元组件,通过挑选选用完成相应的系统

selenium webdriver 工作原理

  1. python + selenium 代码给浏览器驱动dirver.exe发送执行代码命令
  2. 浏览器驱动dirver.exe接收到命令后,驱动浏览器页面进行相应的操作
  3. 操作完成后,返回操作的结果

selenium 教程

一.selenium操作步骤

基本格式

# 导入selenium模块
from selenium import webdriver
# 创建浏览器对象
driver = webdriver.Chrome()
# 输入被测网址(百度)
driver.get("http://www.baidu.com")
# 操作地址、操作网页
pass
# 关闭浏览器
driver.quit()

二.selenium屏蔽谷歌浏览器信息提示栏

from selenium improt webdriver
# 创建谷歌浏览器配置对象
options = webdriver.ChromeOptions()
# 添加参数
options.add_argument('disable-infobars')  # 参数为不显示信息提示栏
driver = webdriver.Chrome(chrome_options=options)
url ="http://www.baidu.com"
driver.get(url)
time.sleep(3)  # pycharm中alt+enter 可以逆向导包
driver.quit()

三.谷歌浏览器模拟移动端

from selenium import webdriver
mobileEmulation = {"deviceName":"iPhone X"}
options = webdriver.ChromeOptions()
options.add_experimental_option("mobileEmulation", mobileEmulation)
driver = webdriver.Chrome(chrome_options=options )
driver.get("http:/www.baidu.com")
driver.quit()

四.浏览器操作

浏览器窗口大小设置

#  设置浏览器界面宽度480,高度800
driver.set_window_size(480, 800)
# 浏览器窗口最大化
driver.maximize_window()

浏览器页面前进后退

# 前进
driver.forward()
# 后退
driver.back()

浏览器页面关闭与刷新

# 刷新浏览器群
driver.refresh()
# 关闭当前浏览器窗口
driver.close()
# 关闭浏览器驱动并退出关联窗口
driver.quit()

五.元素定位

浏览器开发者工具(F12)

开发者工具

  • Element:做页面自动化时查找元素
  • Console:做手工测试时使用,控制台返回代码运行的结果
  • Network:做项目测试时使用,显示当前页面所有请求的接口

什么是元素定位

元素定位就是查找HTML元素的功能
通常使用find_element或find_elements方法定位元素
find_element 使用给定的方法定位查找一个元素
find_elements 使用给定的方法定位查找所有元素,返回一个列表list

元素定位常用方法

html页面中,id是唯一的,name和class是可以重复的

1.元素定位——id(唯一)

当定位的元素具有id属性时可以通过by_id的方式来定位元素

# 通过id定位元素
element = drive.find_element_by_id("id值")
# 查看获取元素的源码
element.get_attribute("outerHTML")
2.元素定位——name、class(重复)
# 通过名字name定位元素
element = driver.find_element_by_name("name属性值")
# 通过class定位元素
element = driver.find_element_by_class_name("class的属性值")
3.元素定位——tag_name(重复)

通过元素的标签名查找元素

# 单数形式(默认查找第一个)
tag_element = driver.find_element_by_tag_name("标签名")
# 复数形式(定位所有的标签元素)
tag_elements = driver.find_elements_by_tag_name("标签名")
4.元素定位——by_link_text / by_partial_link_text

by_link_text通过超文本链接上的文字信息定位元素

# 定位超链接
driver.find_element_by_link_text("超链接文本的全部内容")
# 定位超链接
driver.find_element_by_partial_link_text("超链接文本的部分内容一定是连续的内容")
5.元素定位——xpath

当常用的方法都无法对元素进行定位时,使用xpath系列定位方法

# 通过xpath定位
xpath_type = driver.find_element_by_xpath("//标签名[@属性名="属性值"]")

层级定位:通过其上一级的属性定位该元素

# 通过父级标签属性定位元素(可以多层)
driver.find_element_by_xpath("//父标签[@父标签的属性名="父标签的属性值"]/子标签名")
6.元素定位——通过xpath+索引

当一个父标签有多个相同的子标签时
//父标签[@父标签的属性名=“父标签的属性值”]/子标签名[索引值]
xpath的索引是从1开始的
如果定位的是父标签下的第一个子标签可以不加索引值

# 通过xpath+索引获取元素定位
driver.find_element_by_xpath("//父标签[@父标签属性名="父标签属性值"]/子标签名[子标签的索引值]")

xpath逻辑关系 and(只用and)/or/not
当元素属性与其他元素属性有相同部分的时候,不能只利用一个属性定位,需要多个元素属性来进行定位:——and
//标签名[@属性名=“属性值” and @属性名=“属性值”]
//input[@name=“user” and @class=“login-test”]

# 通过多个属性获取元素定位
driver.find_element_by_xpath("//标签名[@属性名="属性值" and @属性名="属性值"]")

模糊匹配
contains
//标签名[contains(@属性名,属性值或部分属性值)]

7.CSS选择器定位

by_css_selector通过css选择器查找元素。selenium官网的document中极力推荐使用CSS locator ,而不是xpath定位元素。原因是CSS locator比xpath locator速度更快,特别是在IE下比xpath更高效更准确容易编写,对各种浏览器的支持也很好。

# 语法
css_element = driver.find_element_by_css_selector("css表达式")

css中 di、class属性
#表示id属性
.表示class属性
其他属性——标签属性
1)标签名[属性名=属性值]

# id属性定位元素
driver.find_element_by_css_selector("#id值")
# class属性定位元素
driver.find_element_by_css_selector(".class值")
# 使用标签+属性
driver.find_element_by_css_selector("标签名[属性名='"属性值"]")  #属性值如果唯一可以不写标签名

2)层级定位
父标签名[父标签属性名=父标签属性值]>子标签 或 父标签名[父标签属性名=父标签属性值] 子标签

# css层级定位
css_element = driver.find_element_by_css_selector("父标签名[父标签属性名="父标签属性值"]>子标签名")

3)索引定位
#定位子标签
父标签[父属性名=父属性值]>:nth-child(所有子标签的个数索引值) # 索引从1开始
#定位下一级标签
父标签[父属性名=父属性值]>子标签名:nth-of-type(索引值)

# 索引定位
css_element  = driver.find_element_by-css_selector("div#zc>fieldset>p:nth-child(2)>input")
element = driver.find_element_by_css_selector("form[data-bind='submit: submit']>div:nth-of-type(1)>div:nth-of-type(2)>input")

4)逻辑定位
标签名[属性名1=属性值1][属性值2=属性值2]

# 多个属性定位
css_element = driver.fidn_element_by_css_selector("input[type="password"][placeholder="密码A"]")

5)css模糊匹配

# ^ 表示以什么什么开头  匹配到id头
^ = driver.find_element_by_css_selector("input[id ^= "ctrl"]")
# $ 表示以什么什么结尾  匹配到id尾部
$ = driver.find_element_by_css_selector("input[id $= "ctrl"]")
# * 表示中间含有,匹配到id中间含有,如1_ctrl_12
 * = driver.fidn_element_by_css_selector("input[id *= "ctrl" ]")  #  * 匹配全部 常用

六.元素基本操作

元素常用操作方法

  • 元素.clear() 清除文本
  • 元素.send_keys() 模拟输入 先清空后输入
  • 元素.click() 单击元素 按钮/链接/单、复选框。。。
# 代码案例
# 定位账号输入框
user_element = driver.find_element_by_css_selector("#userA")
# 定位访问新浪网站链接
sina = driver.find_element_by_link_text("新浪网站")
# 元素操作
user_element.send_keys("daming")
user_element.clear()
sina.click()
  • 元素.size 返回元素大小
  • 元素.text 获取元素文本
  • 元素.title 获取页面title
  • current_url 获取当前页面url
  • 元素.get_attribute(“属性名”) “获取属性值xxx 要获取的属性 获取对应属性名的值”
  • 元素.is_displayed() 判断元素是否可见 返回True或False
  • 元素.s_enabled() 判断元素是否可用

七.常用操作API

1.鼠标事件
有关鼠标的操作包含在ActionChains类中。
ActionChains类鼠标操作的常用方法:
context_click() ——右击
double_click() ——双击
drag_and_drop(起始元素,终止元素) ——拖动
move_to_element(需要悬停操作的元素) ——鼠标悬停在一个元素上
click_and_hold() —— 按下鼠标左键在一个元素上
perform() —— 执行事件操作 操作后必须加perform()才会执行

# 导入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
# 实例化ActionChains
ActionChains(driver).鼠标操作方法名.perform()

# 鼠标拖拽(两个元素间的拖拽)
red_block = driver.find_element_by_id("div1")
green_block = driver.find_element_by_id("div2")
ActionChains(driver).drag_and_drop(red_block , green_block ).perform()
# 鼠标拖拽(把元素拖动到制定坐标)
ActionChains(driver).drag_and_drop_by_offset(拖拽的元素,x坐标,y坐标).perform()
# 鼠标悬停
ActionChains(driver).move_to_element("元素对象").perform()

2.键盘事件
Keys类提供键盘上所有按键的操作,可以模拟一些组合键的操作ctrl+v/ctrl+A

send_keys(Keys.BACK_SPACE) 删除键(Backspace)
send_keys(Keys.SPACE) 空格键space
send_keys(Keys.TAB) Tab键
send_keys(Keys.ESCAPE) 回退键esc
send_keys(Keys.ENTER) 回车键enter(使用较多)
send_keys(Keys.CONTROL, “a”) 全选ctrl a
send_keys(Keys.CONTROL, “c”) 复制ctrl c
send_keys(Keys.CONTROL, “x”) 剪切ctrl+x
send_keys(Keys.CONTROL, “v”) 粘贴ctrl+v
send_keys(Keys.F1) 键盘F1键

语法
元素.send_keys(Keys.键名) # 键名必须大写——单个键使用
元素.send_keys(Keys.CONTROL, “c”) # 组合键使用

# 导入Keys类
from selenium.webdriver.common.keys import Keys

3.下拉菜单——二次定位
先定位主元素,然后再定位主元素中的子元素

# 元素定位
# 定位主元素
select_element = driver.find_element_by_id("selectA")
# 定位子元素
sub_element = driver.find_element_by_css_selector("option[value=sh]")
# 选择子元素
sub_element.click()

下拉菜单——使用Select类处理下拉菜单(推荐)

语法
# 导入类
from selenium.webdriver.support.select import Select
# 实例化定位下拉菜单元素
select = Select(driver.find_element_by_id("select-demo"))
# 通过value值来选择,例如香蕉
select.select_by_value("banana")
# 通过index选择(索引从0开始)例如香蕉
select.select_by_index(2)
# 通过text选择
select.select_by_visible_text("香蕉")

滚动条操作——javascript
1.设置javascript脚本控制滚动条 js = “window.scrollTo(0, 1000)” 水平距离 垂直距离 (像素)
2.webdriver调用js脚本方法 driver.execute_script(js)

# 向下滚动到底部
js_down = "window.scrollTo(0,1000)"
driver.execute_cript(js_down )
# 向上滚动到顶部
js_up = "window.scrollTo(0, 0)"
driver.execute_script(js_up )

滑动滚动条聚焦到元素的位置

target = driver.find_element_by_xxx()
driver.execute_script("arguments[0].scrollIntoView();", target)

frameset不用切,frame需层层切!
很多人在用selenium定位页面元素的时候会遇到定位不到的问题,明明元素就在那儿,用firebug也可以看到,就是定位不到,这种情况很有可能是frame在搞鬼(原因之一,改天专门说说定位不到元素,可能的一些原因及处理办法)。

frame标签有frameset、frame、iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的,selenium有一组方法对frame进行操作。

1.怎么切到frame中(switch_to.frame())
selenium提供了switch_to.frame()方法来切换frame

switch_to.frame(reference)
不得不提到switch_to_frame(),很多人在这样写的时候会发现,这句话被划上了删除线,原因是这个方法已经out了,之后很有可能会不支持,建议的写法是switch_to.frame()

reference是传入的参数,用来定位frame,可以传入id、name、index以及selenium的WebElement对象,假设有如下HTML代码 index.html:

FrameTest 想要定位其中的iframe并切进去,可以通过如下代码:

from selenium import webdriver
driver = webdriver.Firefox()
driver.switch_to.frame(0) # 1.用frame的index来定位,第一个是0

driver.switch_to.frame(“frame1”) 2.用id来定位
driver.switch_to.frame(“myframe”) 3.用name来定位

driver.switch_to.frame(driver.find_element_by_tag_name(“iframe”)) # 4.用WebElement对象来定位
通常采用id和name就能够解决绝大多数问题。但有时候frame并无这两项属性,则可以用index和WebElement来定位:

index从0开始,传入整型参数即判定为用index定位,传入str参数则判定为用id/name定位
WebElement对象,即用find_element系列方法所取得的对象,我们可以用tag_name、xpath等来定位frame对象
举个栗子:

1 用xpath定位,传入WebElement对象:

driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(@src,‘myframe’)]"))
1
2.从frame中切回主文档(switch_to.default_content())
切到frame中之后,我们便不能继续操作主文档的元素,这时如果想操作主文档内容,则需切回主文档。

driver.switch_to.default_content()
1
3.嵌套frame的操作(switch_to.parent_frame())
有时候我们会遇到嵌套的frame,如下:

1.从主文档切到frame2,一层层切进去

driver.switch_to.frame(“frame1”)
driver.switch_to.frame(“frame2”)

2.从frame2再切回frame1,这里selenium给我们提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来。

driver.switch_to.parent_frame() # 如果当前已是主文档,则无效果

有了parent_frame()这个相当于后退的方法,我们可以随意切换不同的frame,随意的跳来跳去了。

所以只要善用以下三个方法,遇到frame分分钟搞定:

driver.switch_to.frame(reference)
driver.switch_to.parent_frame()
driver.switch_to.default_content()

4.多窗口切换
在页面操作时有时会点击某个链接弹出新的窗口,这时候就需要切换到新打开的窗口上进行操作。
switch_to.window()方法可以实现不同的窗口之间切换。

current_window_handle 获取当前窗口句柄
window_handles 获取所有窗口句柄(列表)
switch_to.window() 切换窗口

# 多窗口切换案例
1.在注册实例页面中输入账号
user = driver.find_element_by_id("user")
user.clear()
user.send_keys("admin")
2.获取当前窗口句柄
handle = driver.current_window_handle()
3.点击注册页面A链接触发多窗口元素
driver.find_element_by_link_text("注册A网页").click()
4.在注册A页面输入账号
# 获取所有窗口句柄
handles = driver.window_handles()
# 进入新窗口
driver.switch_to.window(handles[1])
# 输入账号
userA = driver.find_element_by_id("userA")
userA.clear()
userA.send_keys("adminA")
5.返回到注册实例页面
driver.switch_to.window(handle)

5.浏览器自带弹窗操作
webdriver中处理javascript所生成的alert,confirm以及prompt是很简单的。具体的思路是使用switch_to.alert/confirm/prompt。然后使用相应命令按需要操作。
text 返回弹窗中的文字信息
accept() 点击确认按钮
dismiss() 如果有取消按钮 点击取消按钮
send__keys() 对于可以输入值得弹窗输入值

弹窗操作
1.定位并操作触发弹窗的元素
driver.find_element_by_id("alertA").click()
2.捕获弹窗
alert = driver.switch_to.alert
3.获取弹窗的文本信息
text = alert.text
4.点击弹窗的确认按钮
alert.accept()

处理自定义弹窗

# javascript脚本代码
js = "document.getElementById("id值").style.display="none";"
driver.execute_script(js)

6.单选框(Radio)和复选框(CheckBox)
单选框操作步骤
定位单选框并点击
在操作之前先判断单选框是否已经被选中(is_selected()判断元素是否被选中)

# 单选框操作
# 定位单选框并点击
# 定位单选框内的元素
pear = driver.find_element_by_id("pear")
orange = driver.fidn_element_by_id("orange")
# 判断并点击
if pear.is_selected():
	priint("已经选中")
else:
	pear.click()

复选框操作步骤
如果只选一个 操作方式和单选框一样
全选:复数定位find_elements,遍历列表

# 复选框操作
# 1.全选
# 定位所有复选框
boxes = driver.find_elements_by_css_selector("input[type="checkbox"]")
for box in boxes:
	if box.is_selected():
		pass
	else:
		box.click()

# 2.选择部分
# 将需要选择的复选框以列表的形式储存起来,遍历判断
checkboxs = ["旅行","购物"]
for box in boxes:
	if box.get_attribute("value") in checkboxs:
		if box.is_selected():
			pass
		else:
			box.click()

7.浏览器免登陆
火狐浏览器
1)手动在火狐浏览器中登陆一个网站——记住密码登陆
2)找到火狐浏览器的配置文件路径
菜单—>帮助—>故障排除信息—>配置文件夹 把配置文件夹路径复制
3)使用FirefoxProfile()加载配置项
profile = FirefoxProfile(profile_directory配置文件路径)
driver = webdriver.Firefox(profile)

谷歌浏览器
1)手动在谷歌浏览器中登陆一个网站——记住密码登陆
2)找到谷歌浏览器的个人资料路径
c\user\admin\appdata\locl\google\chrome\user data
3)配置浏览器加载项
options = webdriver.ChromeOptions()
options.add_argument(路径)
4)打开浏览器传入配置
driver = webdriver.Chrome(options=options)

8.操作富文本
大多数富文本都是iframe格式的,操作方式和iframe一致

9.文件上传
针对文件上传功能:html代码input标签,并且type=file时才能使用此方法上传文件
方法:send_keys(需要上传的文件路径)
在上传文件时的文件类型大小等要充分的验证,加一定的等待时间sleep(n)

# 定位文件上传按钮
upfile = driver.find_element_by_name("upfile")
# 执行上传文件操作
upfile.send_keys("要上传的文件路径")

10.下载文件
可以上网查看搜索资料

Chrome浏览器文件下载
Chrome浏览器,设置其options:

download.default_directory:设置下载路径
profile.default_content_settings.popups:设置为 0 禁止弹出窗口

它的设置就简单多了,看个示例:
#-- coding: utf-8 --
from selenium import webdriver
from time import sleep

options = webdriver.ChromeOptions()
prefs = {‘profile.default_content_settings.popups’: 0, ‘download.default_directory’: ‘d:\’}
options.add_experimental_option(‘prefs’, prefs)

driver = webdriver.Chrome(executable_path=‘D:\chromedriver.exe’, chrome_options=options)
driver.get(‘http://sahitest.com/demo/saveAs.htm’)
driver.find_element_by_xpath(’//a[text()=“testsaveas.zip”]’).click()
sleep(3)
driver.quit()

八.网络

1.cookie/session/token
因为HTTP协议是无连接无状态的(不会记录刚才谁建立了请求和谁建立了链接)
cookie——记录用户信息 (不安全)
cookie保存在客户端(浏览器)
cookie保存的信息按照键值对形式保存,其中有一个sessionID(sessionID和用户的IP地址绑定)
session
session保存在服务端(服务器)
token——针对移动端
登陆一次使用一次,使用过就会失效,不会保存

记录cookie的作用:
1.用户第一次登陆时,勾选下次直接登陆或者记住密码,采用记录cookie实现的
2.cookie内记录用户名和密码信息,只要请求时服务器收到cookie就识别成功,默认已登陆。

webdiver操作cookie的方法
get_cookies() 获取所有cookie信息 返回[{}, {}, {}]
get_cookie(name) 获取指定名称name的cookie信息
add_cookie(cookie_dict) 添加cookie 必须有name 和 value {“name”:name值,“value”:value值}

cookie本身属性
domain——cookie的域名
httponly——预防xss攻击(跨站脚本攻击)
name——cookie名称,必须存在的属性
path——cookie产生保存的路径
secure——定义cookie安全性
value——cookie名称对应的值,必须存在的属性
expiry——cookie的有效期

2.验证码操作
1.让开发人员在测试时将验证码去掉(开发承担风险)
2.设置万能验证码
3.验证码识别技术(不推荐使用)
4.记录cookie免登陆
获取登陆后的cookie——通过浏览器F12或抓包工具得到
将登陆后的cookie添加到脚本中——driver.add_cookie(字典)
执行刷新操作——driver.refresh()
5.设置浏览器加载项

cookies = [
{'name':'name值',value:'value值'}
{'name':'name值',value:'value值'}
]
for cookie_dict in cookies:
	driver.add_cookie(cookie_dict)
driver.refresh()
driver.quit()
注意:
1.先正常登陆一次
2.明确哪些cookie属性和登陆相关
3.使用cookie做免登陆,原来的登陆的账号是不能退出的,退出cookie会失效

九.selenium高级

1.元素等待
元素等待定义:webdriver定位页面元素时,如果未找到,会在指定时间内一直等待的过程。为了保证脚本运行的稳定性,需要在脚本中添加等待时间

设置元素等待的原因:
1.由于网络速度原因
2.电脑配置原因
3.服务器处理请求原因
selenium中常用的等待时间方式有三种:显示等待,隐式等待,sleep

隐式等待:
隐式等待针对整个页面上的所有元素

隐式等待是通过一定的时长等待页面中所有元素加载完成,如果超出了设置的时长,元素还没被加载则会抛出NoSuchElementException异常
driver.implicitly_wait() 实现隐式等待,默认单位为秒(最大等待时间)

显式等待:
在设定时间内,针对某一个元素,默认每隔一段时间检测该元素是否存在,如果超过设定时间检测不到则抛出异常

# 导入模块
from selenium.webdriver.support.wait import WebDriverWait
# 调用类
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_excetions=None)
	driver——webdriver驱动程序
	timeout——最长超时时间(秒)
	poll_frequency——休眠时间间隔(默认0,5秒)
	ignored_excetions——超时后的异常信息
# 方法
until(method, message=" ")
	method:在等待期间,每隔一段时间调用这个传入方法(lambda),直到返回True
	message:如果超时,抛出timeout异常,将message传入异常
until_out 与until相反

# 显示等待配合元素定位
user = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("id属性值"))
user.send_keys("find it")

2.expected_conditions 模块(EC模块)
expected_conditions模块可以对网页上元素是否存在、可点击等进行判断,一般用于断言或与WebDriverWait配合使用。
通常会对类重命名为EC
详细方法上网查询

# 导入类
from selenium.webdriver.support import expected_conditions as EC
# EC模块通用使用方法
WebDriverWait(driver, timeout).until(EC.方法) 

presence_of_element_located(locator) 判断一个元素存在于页面DOM树下,则返回元素本身,不存在则报错。locator为一个(by,path)元组,这个元组中by为selenium的一个雷,包括CLASS_NAME, CSS_SELECOTR,XPATH,LINK_TEXT等元素定位的方式,和在元素定位中使用的方法相同。path则为该属性名的属性值。

操作语法:WebDriverWati(driver, timeout).until(EC.presence_of_element_located(locator))
locator:定位器是一个元组(定位方法,方法对应的值) 例(“id”, “userA”)
(“class name”,“telA”) (“partial link text”, “访问”)

十.自动化测试用例

1.自动化用例选型
1.不是所有手工用例都需要转化为自动化测试用例
2.不要选择流程太复杂的用例,如果有必要,可以考虑拆分多个用例来实现
3.选择的用例最好可以构建成一个场景,如一个个功能模块。
4.选择用例带有目的性
5.选取的用例是重复执行的
6.主体流程
7.自动化测试可以用来做配置检查
8.提升效率

2.自动化用例编写原则
1.一个脚本就是一个完整的场景
2.一个脚本只验证一个功能点
3.尽量只做功能中的正向逻辑(只走主线)验证
4.脚本之间不要产生关联性,每个脚本可以独立运行
5.脚本只对验证点进行验证,不对脚本中每一步骤做验证

# 编写ECshop登陆脚本案例
# 导入
from selenium.webdriver.support.wait  import WebDriverWait
from seleniumwebdriver.support import expected_conditions as EC
from selenium import webdriver
from time import sleep

# 实例化浏览器对象
driver = webdriver.Chrome()
# 访问网址
url = ""
driver.get(url)
sleep(3)

# 登录
# 输入用户名
user_locator = ("name", "username") # 用户名输入框定位器
username = WebDriveWait(driver, 10).until(EC.presence_of_element_locator(user_locator ))
username.clear()
username.send_keys("daming")
# 输入密码
pwd_locator = ("name", "password")
password = WebDriverWait(driver, 10).until(EC.presence_of_element_locator(pwd_locator )) 
password.clear()
password.send_keys("123456")
# 点击登陆按钮
button_locator = ("name", "submit")
submit = WebDriverWait(driver, 10).until(EC.presence_of_element_locator(button_locator ))
submit.click()
sleep(5)
# 判断是否登陆成功
result_locator = ("class name", "f4_b")
username_input = "daming"
result = WebDriverWait(driver, 10).until(EC.text_to_be_present_in_element(result_locator , username_input))
if result:
	print("登陆成功!")
# 退出浏览器驱动
driver.quit()

3.POM模型
pom模式是页面自动化的一个常用的模式 page object module 页面对象模型
核心思想:一切皆对象

  • 把项目中的每一个页面当做一个对象
  • 把每个页面分为三层 表现层(页面上所有可见元素)、操作层(对页面上所有可见元素的操作-点击,清空,输入)、业务层(对元素操作后所实现的功能)

POM框架文件结构

项目名称
 	common文件夹——存放公共方法
 		base.py 对selenium做二次封装
 		工具类
 			operation_excel.py
 			xxx.py
 	page文件夹——一个页面就是一个py文件
 		封装页面的表现层和操作层—继承base.py
 		login_page.py
 		register_page.py
 	script文件夹
 		封装页面的业务层(测试用例)
 	data文件夹——存放测试数据
 	report——存放测试报告

十一.测试框架

1.Unittest(pyUnit)
unittests是python自带的一个单元测试框架。使用unittest帮助我们管理自动化测试用例
import unittest
unittest四个基本构件:

  1. 测试夹具——test fixture 处理测试用例(类)运行前后数据和方法的处理(前置条件)
  2. 测试套件——test suite 收集测试用例
  3. 测试用例——test case
  4. 测试执行——test runner 执行单个用例、执行批量用例(测试套件中的测试用例)

创建测试类要求

  • 创建测试类以Test开头,并且继承unittest中的TestCase
  • 测试类中包含四个特殊方法
  • 测试类中包含测试用例(测试用例以test开头)

特殊方法test fixture
setup——在每个测试用例执行前执行
deardown——在每个测试用例执行后执行
setupclass——在测试类执行前执行需要@classmethod修饰
teardownclass——在测试类执行后执行需要@classmethod修饰

跳过测试装饰器
@unittest.skip(跳过原因)——无条件跳过
@unittest.skipif(判断条件,跳过原因)——当条件为真时跳过测试
@unittest.skipUnless(判断条件,跳过原因)——当条件为假时跳过测试
@unittest.expectedFailure——标记失败

2.断言
在执行测试用例的过程中,最终用例是否执行通过,是通过判断测试得到的实际结果和预期结果是否相等来决定的,这时就用到断言方法。
#步骤

  1. 导入模块 - unittest
  2. 创建类,并继承 - unittest.TestCase
  3. 定义实例方法,必须以test开头
  4. 实例方法内部细节:
    1. response = app.test_client().post(’/login’, data = {})
    2. resp_data = response.data # 接收返回的数据。为二进制的形式的字典
    3. json_dict = json.loads(resp_data) # 转为json形式的字典
    4. 根据判断条件,开始断言:
      self.assertIsNotNone(json_dict, ‘未获取到返回数据’)
      self.assertIn(‘errcode’, json_dict, ‘返回数据格式不正确’)
      errcode = json_dict.get(‘errcode’)
      self.assertEqual(errcode, -2, ‘返回的状态码错误’)
  5. setUp实例方法:在开始执行测试的方法之后会调用该方法,该方法里面可以做一些初始化操作,比如:
    app.testing = True # 单元测试开启,可以知道在哪行代码出错
  6. tearDown实例方法:在执行测试方法结束之后会调用该方法,可以做数据的清除操作
  7. 除了使用鼠标右键点击测试,还可以使用unittest.main(),再用命令行启动开启测试

生成测试报告
见pycharm web文件夹下的ecshop

你可能感兴趣的:(selenium)