web-selenium
简介
可解决:回归测试,压力测试,兼容性测试
工具:QTP(收费,支持web,桌面软件自动化),Selenium(免费,开源,支持web),Robot framework(基于python的扩展关键字自动化工具)
安装
注意:浏览器驱动版本必须和浏览器版本一致
案例
yacas
from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
sleep(3)
driver.quit()
元素定位
元素定位:通过元素的信息或元素的层级结构来定位元素
4.1 为什么要使用元素定位?
要使用web自动化操作元素,必须首先找到此元素。
4.2 定位工具
火狐:Firebug (F12获取直接点击 Friebug图标)
谷歌:F12键(开发者工具)
4.3 定位元素时依赖于什么?
1. 标签名
2. 属性
3. 层级
4. 路径
4.4 定位方式
1. id
2. name
3. class_name(使用元素的class属性定位)
4. teg_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书写来定位元素,HTML规定id属性在整个HTML文档中必须是唯一的
前提:元素有id属性
id定位方法
yacas
element=driver.find_element_by_id(id)
注意:url中的链接/表示转义,//表示/,使用本地的链接前缀用file:///
id定位拓展
yacas
#查找元素用户名并且输入admin
driver.find_element_by_id("userA").send_keys("admin")
name,class_name
name定位就是根据元素name属性来定位。HTML文档中name的属性值是可以重复的。
前提:元素有name属性
name定位
yacas
element=driver.find_element_by_name(name)
name定位拓展
yacas
#查找元素用户名并且输入admin
driver.find_element_by_name("userA").send_keys("admin")
class_nam定位
说明:class_name 是根据class属性值来定位元素。HTML通过使用class来定义元素的样式
前提:元素有class属性
注意:如果class有多个属性值,只能使用其中的一个
代码:
yacas
element=driver.find_element_by_class_name(class_name)
tag_name
说明
tag_name,通过标签名定位,但一般存在多个相同的标签名,如果存在多个同样的标签,默认返回第一个,所以很少使用tag_name
代码
yacas
element=driver.find_element_by_tag_name(tag_name)
link_text,partial_link_text
link_text说明
专门定位超链接,并且是超链接()的文本内容
代码
yacas
element=driver.find_element_by_link_text(link_text)
其中link_text为超链接的文本内容
partial_link_text说明
对link_text的补充,partial_link_text除了可以使用全部文本匹配元素还可以使用局部来匹配元素,局部没有唯一代表词,默认操作符合条件的第一个元素
代码
yacas
element=driver.find_element_by_partial_link_text(partial_link_text)
partial_link_text可以传入a标签局部文本,模糊部分值,但必须能够表达唯一性
使用XPath,CSS原因
1.没有id,name,class属性使用XPath
2.link_text,partial_link_text 只适合超链接
3.tag_name只能找页面唯一的元素或者页面多个相同元素中第一个元素
XPath
XML Path的简称,是一门在XML文档中查找元素信息的语言
HTML可以看作是XML的一种实现,所以selenium用户可以使用这种强大的语言在web应用定位元素
XML:一种标记语言,用户数据的存储和传递,后缀.xml结尾
XPath定位:基于元素的路径
XPath定位策略(方式)
1.路径定位
2.利用元素属性定位
3.属性和逻辑结合定位
4.层级和属性结合定位
XPath定位方法
yacas
element=driver.find_element_by_xpath(xpath)
chromeXPath
F12 右键点击copy,右边会弹出来一列,可以看到XPath和fullpath
火狐XPath定位示例
2.4 Xpath常用的定位策略:
1. 路径
1). 绝对路径:
语法:以单斜杠开头逐级开始编写,不能跳级。如:/html/body/div/p[1]/input
2). 相对路径
语法:以双斜杠开头,双斜杠后边跟元素名称,不知元素名称可以使用*代替。
如: //input
//*
2. 路径结合属性
语法:在Xpath中,所有的属性必须使用@符号修饰 如://*[@id='id值']
3. 路径结合逻辑(多个属性)
语法://*[@id="id值" and @属性='属性值']
4. 路径结合层级
语法://*[@id='父级id属性值']/input
提示:
1. 一般见识使用指定标签名称,不使用*代替,效率比较慢。
2. 无论是绝对路径和相对路径,/后面必须为元素的名称或者*
3. 扩展:在工作中,如果能使用相对路径绝对不使用绝对路径。
2.5 Xpath扩展
1. //*[text()='XXX'] # 定位文本值等于XXX的元素
提示:一般适合 p标签,a标签
2. //*[contains(@属性,'xxx')] # 定位属性包含xxx的元素 【重点】
提示:contains为关键字,不可更改。
3. //*[starts-with(@属性,'xxx')] # 定位属性以xxx开头的元素
提示:starts-with为关键字不可更改
CSS
css说明
说明:
1. CSS一种标记语言,焦点:数据的样式。控制元素的显示样式,就必须先找到元素,在css标记语言中找元素使用css选择器;
2. css定位就是通过css选择器工具进行定位。
3. 极力推荐使用,查找元素的效率比xpath高,语法比xpath更简单。
css定位语法
yacas
element = driver.find_element_by_css_selector(css_selector)
常用测试略:
1. id 选择器
前提:元素是必须有id属性
语法:#id 如:#passwordA
2. class 选择器
前提:元素是必须有class属性
语法:.class 如:.telA
3. 元素选择器
语法:element 如:input
4. 属性选择器
语法:[属性名=属性值]
5. 层级选择器
语法:
1. p>input
2. p input
提示:>与空格的区别,大于号必须为子元素,空格则不用。
扩展:
1. [属性^='开头的字母'] # 获取指定属性以指定字母开头的元素
2. [属性$='结束的字母'] # 获取指定属性以指定字母结束的元素
3. [属性*='包含的字母'] # 获取指定属性包含指定字母的元素
复制xpath:/html/body/form/div/fieldset/p[1]/input
复制最简://*[@id="userA"]
复制CSS路径:html body form div#zc fieldset p#p1 input#userA
提示:
1. 虽然借助工具可以快速生成xpath路径和css语法,但是前期不建议使用。
2. 工具在智能,没有人智能。
P37?拓展工具生成XPath,CSS
定位一组元素
方法:driver.find_elements_by_xxx()
返回结果:类型为列表,需要对列表进行访问和操作必须指定下标或进行遍历,[下标从0开始]
拓展8种元素定位的底层实现
方式:driver.find_element(By.xxx,'value')
参数说明:
value:元素的定位值 如:userA
By类:需要导包 位置:from selenium.webdriver.common by import By
元素的操作方法
操作元素的方法
1.让脚本模拟用户给指定元素输入值
2.让脚本模拟认为删除元素的内容
3.让脚本模拟点击操作
元素常用操作的方法
1.click() 单击元素
2.send_keys(value) 模拟输入
3.clear() 清除文本
提示:在输入方法前一段要清空操作
操作浏览器常用方法API
2.1 方法
1). driver.maximize_window() # 最大化浏览器
2). driver.set_window_size(w, h) # 设置浏览器大小 单位像素
3). driver.set_window_position(x, y) # 设置浏览器位置
4). driver.back() # 后退操作
5). driver.forward() # 前进操作
6). driver.refresh() # 刷新操作
7). driver.close() # 关闭当前主窗口(主窗口:默认启动哪个界面,就是主窗口)
8). driver.quit() # 关闭由driver对象启动的所有窗口
9). driver.title # 获取当前页面title信息
10). drive.current_url # 获取当前页面url信息
2.2 提示:
1. driver.title 和 driver.current_url 没有括号,应用场景:一般为判断上步操作是否执行成功。
2. driver.maximize_window() # 一般为我的前置代码,在获取driver后,直接编写最大化浏览器
3. driver.refresh() 应用场景,在后面的cookie章节会使用到。
4. driver.close()与driver.quit()区别:
close():关闭当前主窗口
quit():关闭由driver对象启动的所有窗口
提示:如果当前只有1个窗口,close与quit没有任何区别。
python
# 最大化浏览器
driver.maximize_window()
# 刷新
driver.refresh()
# 后退
driver.back()
# 前进
driver.forward()
# 设置浏览器大小
driver.set_window_size(300,300)
# 设置浏览器位置
driver.set_window_position(300,200)
# 关闭浏览器单个窗口
driver.close()
# 关闭浏览器所有窗口
driver.quit()
# 获取title
title = driver.title
# 获取当前页面url
url = driver.current_url
获取元素信息的常用方法
3.1 方法:
1). text 获取元素文本 如:driver.text
2). size 获取元素大小 如:driver.size
3). get_attribute 获取元素属性值 如:driver.get_attribute("id")
4). is_displayed 判断元素是否可见 如:element.is_displayed()
5). is_enabled 判断元素是否可用 如: element.is_enabled()
6). is_selected 判断元素是否被选中 如:element.is_selected()
3.2 提示:
1. text和size调用时 无括号
2. get_attribute一般应用场景:判断一组元素是否为想要的元素或者判断元素属性值是否正确
3. is_displayed、is_enabled、is_selected,在特殊应用场景中使用。
鼠标和键盘的操作
鼠标的操作
4.1 为什么使用鼠标操作?
为了满足丰富的html鼠标效果,必须使用对应的方法。
4.2 鼠标事件对应的方法在哪个类中
ActionChains类--->导包
from selenium.webdriver.common.action_chains import ActionChains
4.3 鼠标事件常用的操作方法
1. context_click() # 右击
应用:context_click(element).perform()
2. double_click() # 双击
应用:double_click(element).perform()
3. drag_and_drop() # 拖拽
应用:drag_and_drop(source, target).perform
4. move_to_element() #悬停
应用: move_to_element(element).perform()
5. perform() # 执行以上事件方法
4.4 提示:
1. selenium框架中虽然提供了,右击鼠标方法,但是没有提供选择右击菜单方法,可以通过发送快捷键的方式解决(经测试,谷歌浏览器不支持)。
其他:鼠标实例化对象
action=ActionChains(driver)
键盘操作
4.1 键盘对应的方法在Keys类中
包:from selenium.webdriver.common.keys import Keys
4.2 常用的快捷键:
CONTROL:Ctrl键
其他,请参考Keys底层定义的常亮
4.3 应用
组合键:element.send_keys(Keys.XXX, 'a')
单键:element.send_keys(Keys.XXX)
q元素等待
6.1 为什么要设置元素等待
由于电脑配置或网络原因,在查找元素时,元素代码未在第一时间内被加载出来,而抛出未找到元素异常。
6.2 什么是元素等待
元素在第一次未找到时,元素等待设置的时长被激活,如果在设置的有效时长内找到元素,继续执行代码,如果超出设置的时长未找打元素,抛出未找到元素异常。
6.3 元素等待分类
1. 隐式等待
2. 显示等待
6.4 隐式等待
方法:driver.implicitly_wait(30) # 一般情况下设置30秒
特色:
1. 针对所有元素生效。
2. 一般情况下为前置必写代码(1.获取浏览器驱动对象;2. 最大化浏览器;3. 设置隐式等待)
6.5 显示等待
方法: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;
提示:
1. WebDriverWait(driver,timeout=10, poll_frequency=0.5).until(lambda x:x.find_element_by_id("#user"))返回的一个元素。
6.6 显示等待与隐式等待区别:
1. 显示等待:针对单个元素生效
2. 隐式等待:针对全局元素生效
拓展send_keys 上传文件
下拉框
1.1 为什么单独使用下拉框?
1. 如果option选项没有value值的化,css定位或其他定位就不太方便。
1.2 如何使用Select类
操作:
1. 导包:from selenium.webdriver.support.select improt Select
2. 实例化:s = Select(element)
3. 调用方法:s.select_by_index()
1.3 提供哪些方法
1. select_by_index() # 通过下标定位
2. select_by_value() # 通过value值
3. select_by_visible_text() #显示文本
1.4 注意事项
1. 实例化select时,需要的参数为 select标签元素
2. 调用Select类下面的方法,是通过索引、value属性值、显示文本去控制,而不需要click事件
警告框
2.1 为什么要处理警告框?
如果页面由弹出框,不处理,接下来的将不生效。
2.2 对话框类型
1. alert # 警告框
2. confirm # 确认框
3. prompt # 提示框
2.3 如何处理
以上三种对话框,处理方法都一样。
步骤:
1. 切换到对话框
方法:driver.switch_to.alert
2. 处理对话框
alert.text # 获取文本
alert.accept() # 同意
alert.dismiss() # 取消
提示:无论以上哪个对话框,都可以使用取消、同意,因为调用的是后台的事件,根页面显示的按钮数量无关。
2.4 注意:
1. driver.switch_to.alert 方法适合以上三种类型对话框,调用时没有括号
2. 获取文本的方法,调用时没有括号 如:alert.text
3. 在项目中不是所有的小窗口都是以上三种对话框。
滚动条
3.1 为什么要操作滚动条
在web自动化中有些特殊场景,如:滚动条拉倒最底层,指定按钮才可用。
3.2 如何操作
第一步:设置操作滚动条操作语句
如:js = "window.scrollTo(0,10000)"
0: 左边距 --》水平滚动条
10000:上边距 -->垂直滚动条
第二步:调用执行js方法,将设置js语句传入方法中
方法:driver.execute_script(js)
3.3 说明
在selenium中没有直接提供定位滚动条组件方法,但是它提供了执行js语句方法,可以通过js语句来控制滚动条操作。
切换frame表单和多窗口切换
切换frame表单
提示:常用的frame表单有两种:frame、iframe
4.1 为什么要切换?
当前主目录内没有iframe表单页面元素信息,不切换,找不到元素。
4.2 如何切换?
方法:driver.switch_to.frame("id\name\element")
4.3 为什么要回到主目录
iframe或frame只有在主目录才有相关元素信息,不回到主目录,切换语句会报错。
4.4 如何回到主目录
方法:driver.switch_to.default_content()
4.5 提示:
1.切换frame时,可以使用name、id、iframe元素
多窗口切换
5.1 为什么要切换多窗口?
页面存在多个窗口式,seleniu默认焦点只会在主窗口上所有的元素,不切换切换窗口,无法操作除主窗口以外的窗口内元素
5.2 如何切换?
思路:获取要切换的窗口句柄,调用切换方法进行切换。
方法:
1. driver.current_window_handle # 获取当前主窗口句柄
2. driver.window_handles # 获取当前由driver启动所有窗口句柄
3. driver.switch_to.window(handle) # 切换窗口
步骤:
1. 获取当前窗口句柄
2. 点击链接 启动另一个窗口
3. 获取当前所有窗口句柄
4. 遍历所有窗口句柄
5. 判断当前遍历的窗口句柄不等于当前窗口句柄
6. 切换窗口操作
截屏
应用场景:失败截图,让错误看的更直观
方法:
driver.get_screenshot_as_file(imgepath)
参数:
imagepath:为图片要保存的目录地址及文件名称
如: 当前目录 ./test.png
上一级目录 ../test.png
扩展:
1. 多条用例执行失败,会产生多张图片,可以采用时间戳的形式,进去区分。
操作:
driver.get_screenshot_as_file("../image/%s.png"%(time.strftime("%Y_%m_%d %H_%M_%S")))
strftime:将时间转为字符串函数
注意:
%Y_%m_%d %H_%M_%S:代表,年 月 日 时 分 秒
验证码
7.1 什么是验证码?
一种随机生成信息(文字、数字、图片)
7.2 验证码作用
防止恶意请求
7.3 验证码处理方式
1. 去掉验证码(项目在测试环境、公司自己的项目)
2. 设置万能验证码(测试环境或线上环境,公司自己项目)
3. 使用验证码识别技术 (由于现在的验证码千奇百怪,导致识别率太低)
4. 使用cookie解决(推荐)
7.4 cookie 介绍:
生成:由服务器生成
作用:标识一次对话的状态(登录的状态)
使用:浏览器自动记录cookie,在下一条请求时将cookis信息自动附加请求
7.5 应用:
方法:
1. driver.get_cookies() # 获取所有的cookie
2. driver.add_cookies({字典}) # 设置cookie
步骤:
1. 打开百度url driver.get("http://www.baidu.com")
2. 设置cookie信息: driver.add_cookie({"name":"BDUSS","value":"根据实际情况编写"})
3. 暂停2秒以上
4. 刷新操作
注意:
1. 以上百度BDUSS所需格式为百度网站特有,别的网站请自行测试。
2. 必须进行刷新操作。
unittest
一、UnitTest框架
1.1 为什么使用UnitTest框架?
1. 批量执行用例
2. 提供丰富的断言知识
3. 可以生成报告
1.2 什么是UnitTest框架
python自带一种单元测试框架
1.3 核心要素
1). TestCase(测试用例)
2). TestSuite(测试套件)
3). TextTestRunner(以文本的形式运行测试用例)
4). TestLoader(批量执行测试用例-搜索指定文件夹内指定字母开头的模块) 【推荐】
5). Fixture(固定装置(两个固定的函数,一个初始化时使用,一个结束时使用))
TestCase:
说明:测试用例
步骤:
1. 导包 import unittest
2. 新建测试类并继承 unittest.TestCase
3. 测试方法必须以test字母开头
运行:
1. 运行测试类所有的测试方法,光标定位到类当前行右键运行
2. 运行单个测试方法:光标放到测试方法当前行。
TestSuite:
说明:测试套件
步骤:
1. 导包
2. 获取测试套件对象 suite = unittest.TestSuite()
3. 调用addTest()方法 添加测试用例
添加测试用例方法:
1. suite.addTest(类名("方法名称")) # 添加指定类中指定的测试方法
2. suite.addTest(unittest.makeSuite(类名)) # 添加指定类中所有已test开头的方法
TextTestRunner:
说明:执行测试套件方法
步骤:
1. 导包
2. 实例化后去执行套件对象 runner = unittest.TextTestRunner()
3. 调用run方法去执行 runner.run(suite)
TestLoader:
说明:
1. 将符合条件的测试方法添加到测试套件中
2. 搜索指定目录文件下指定字母开头的模块文件下test开始的方法,并将这些方法添加到测试套件中,最后返回测试套件
操作:
1. 导包
import unittest
2. 调用TestLoader()
写法1. suite = unittest.TestLoader().discover("指定搜索的目录文件","指定字母开头模块文件")
写法2. suite = unittest.defaultTestLoader.discover("指定搜索的目录文件","指定字母开头模块文件") 【推荐】
注意:如果使用写法1,TestLoader()必须有括号。
3. 执行测试套件
unittest.TextTestRunner().run(suite)
TestSuite与TestLoader区别:
共同点:都是测试套件
不同点:实现方式不同
TestSuite: 要么添加指定的测试类中所有test开头的方法,要么添加指定测试类中指定某个test开头的方法
TestLoader: 搜索指定目录下指定字母开头的模块文件中以test字母开头的方法并将这些方法添加到测试套件中,最后返回测试套件
二、fixture
说明:装置函数(setUp、tearDown)
级别:
1). 函数级别 def setUp() / def tearDown()
特性:几个测试函数,执行几次。每个测试函数执行之前都会执行 setUp,执行之后都会执行tearDwon
2). 类级别 def setUpClass() / def tearDownClass()
特性:测试类运行之前运行一次setUpClass 类运行之后运行一次tearDownClass
注意:类方法必须使用 @classmethod修饰
3). 模块级别:def setUpModule() / def tearDownModule()
特殊:模块运行之前执行一次setUpModule ,运行之后运行一次tearDownModule
提示:
无论使用函数级别还是类级别,最后常用场景为:
初始化:
1. 获取浏览器实例化对象
2. 最大化浏览器
3. 隐式等待
结束:
关闭浏览器驱动对象
三、断言
3.1 什么是断言?
让程序代替人为判断执行结果是否与预期结果相等的过程
3.2 为什么要断言?
自动化脚本执行时都是无人值守,需要通过断言来判断自动化脚本的执行是否通过
注:自动化脚本不写断言,相当于没有执行测试一个效果。
3.3 常用断言
1. self.assertEqual(ex1, ex2) #判断ex1 是否相等ex2
2. self.assertIn(ex1 ,ex2) # ex2是否包含ex1 注意:所谓的包含不能跳字符
3. self.assertTrue(ex) # 判断ex是否为True
3.4 断言练习
目标:tpshop登录
方法:
def setUp():
# 获取driver
# 打开url
# 最大化浏览器
# 隐式等待
def tearDown():
# 关闭浏览器驱动
def test_login_code_null():
# 根据业务流程编写
# ...
# 失败截图
3.5 扩展
断言两种实现方式
方式1:使用unittest框架中断言,详情请参考以上相关知识点。
方式2:使用python自带断言
1. assert str1 == str2 # 判断str1 是否与str2相等
2. assert str1 in str2 # 判断str2 是否包含str1
3. assert True/1 # 判断是否为True
四、参数化
4.1 为什么要参数化
解决冗余代码问题;
4.2 什么是参数化
说明:根据需求动态获取参数并引用的过程
4.3 参数化应用场景
场景:解决相同业务逻辑,不同测试数据问题。
4.4 应用:
1. 安装插件
通过命令:
安装:
pip install parameterized
验证:
pip show parameterized
通过pycharm:File-->setting-->Project 工程名称
2. 应用插件
1. 导包 from parameterized import parameterized
2. 修饰测试函数 @parameterized.expand([数据])
数据格式:
1. 单个参数:类型为列表
2. 多个参数:类型为列表嵌套元祖
3. 在测试函数中的参数设置变量引用参数值,注意:变量的数量必须和数据值的个数相同
with opren 和 open的区别
1.共同点:打开文件
2.不同点,with open =执行操作+关闭操作
P104 PO模式
PO模式
版本:
v1:不采用任何模式(线性模型)
v2:采用测试框 unittest
v3:业务代码和页面对象进行
v4:实际中的po模式编写
案例:
tpshop登录
1. 账号不存在
2. 密码错误
问题:
v1:无法批量运行
v2: 业务脚本与页面对象没有分开
v3: 代码冗余量太大
PO介绍:
PO: page(页面) object(对象)
v4版本:
结构:
1. base(基类):page页面一些公共的方法;
# Base类
# 初始化方法
# 查找元素方法
# 点击元素方法
# 输入方法
# 获取文本方法
# 截图方法
注意:
1. 以上方法封装时候,解包只需1此,在查找元素解包;
2. driver为虚拟,谁调用base时,谁传入,无需关注从哪里来;
3. loc:真正使用loc的方法只有查找元素方法使用;
2. page(页面对象):一个页面封装成一个对象;
应用:继承base;
实现:
1. 模块名:page+实际操作模块名称 如:page_login.py
2. 页面对象名:以大驼峰方法将模块名抄进来,有下划线去掉下划线
3. 方法:涉及元素,将每个元素操作单独封装一个操作方法;
4. 组装:根据需求组装以上操作步骤;
3. scripts(业务层):导包调用 page页面
实现:
1. 模块:test+实际操作模块名称 如:test_login.py
2. 测试业务名称:以大驼峰方法将模块名抄进来,有下划线去掉下划线
3. 方法:
1. 初始化方法 setUp() 注:在unittest框架中不能使用def __init__()初始化方法;
# 实例化 页面对象
# 前置操作 如:打开等等
2. 结束方法 teardown
# 关闭驱动
3. 测试方法
# 根据要操作的业务来实现
扩展:
loc变量:类型为元组 ;*loc为解包;
今天目标:
1. 数据驱动
扩展:
1. 线性驱动
2. 模块驱动
3. 数据驱动
一、数据驱动
1.1 什么是数据驱动?
说明:
1. 通过测试数据控制用例的执行,直接影响测试结果;
2. 数据驱动是最好结合PO+参数化技术使用;
1.2 数据驱动优点
将维护关注点放到测试数上,而不去关注测试脚本代码;
1.3 数据驱动常用的格式
1. JSON(重点)
2. XML
3. EXCEL
4. CSV
5. TXT
1.4 JSON介绍
1. 一种纯文本格式,后缀.json ;
2. 一种轻量级数据交换格式;(接口数据传递基本使用json格式)
3. 由键值对组成,和python的字典格式一模一样,不同之处在于(json是文本格式)
4. json语法:花括号包含键值对,键与值之间使用冒号(:)分隔, 键值对之间使用逗号(,)分隔;
1.5 json与字典转换
1). 字典转为json字符串
方法:dumps()
操作:
1. 导包
2. 调用dumps方法
3. 打印类型
注意:
使用dumps方法,而不是dump方法;
2) json字符串转字典
方法: loads()
操作:
1. 导包
2. 调用loads方法
3. 打印类型
注意:
1. 使用loads方法而不是load方法
2. 字符串中的键名必须使用双引号;
1.6 json的写与读
1). 写入json
方法:dump(写什么文件, 往那写)
操作:
1. 导包
2. 获取文件流f,并调用dump方法写入
注意:
1. 写入时模式 w
2. 写入的方法 dump() 而不是 dumps()
2). 读取json 【重点】
方法:load()
操作:
1. 导包
2. 获取文件流f,并调用load方法读取
注意:
1. 写入时模式 r
2. 写入的方法 load() 而不是 loads()
二、练习计算器
链接:http://cal.apple886.com/
结构:
base
# 初始化方法
# 查找元素
# 点击
# 获取value属性方法封装
# 截图
page
# 点击数字
for n in num:
loc = By.ID, ""simple{}".format(n)"
# 调用baes内点击方法
# 点击加号
# 点击等号
# 获取结果
# 组装业务方法
scripts
# 初始化方法
# 获取计算页面页面对象
# 获取driver
# 结束方法
# 关闭driver
# 测试加法方法
# 调用加法运算业务方法
# 断言
注意:断言在业务层
注意:结构化可以运用yeild生成器
生成器的本质就是一个迭代器
迭代器和生成器的区别: 迭代器是Python中内置的一种节省空间的工具,是python自带的;生成器是程序员自己写的。
drvier封装
类名
# 定义类变量
driver = None
@classmethod
# 获取driver方法
如果 cls.driver is None:
# 获取浏览器驱动对象
# 最大化
# 打开url 注:url建议写入配置文件中
返回 cls.driver
@classm3thod
# 关闭driver方法
如果 cls.driver:
cls.driver.quit()
# 注意此处一定要置空
cls.driver = None
读取json数据封装
1. 读取工具封装
# 导包
# 打开json获取文件流 并 调用load方法
2. 组装读取出来数据格式封装
预期格式:[(),()]
默认实际格式:{"":"","":""}
思路:
1. 新建空列表
2. 使用字典.values()方法获取所有的字典值;
3. 使用列表的.append((字典.get("键名")))
4. 返回 arrs
查找元素判断是否操作成功 思路封装
def base_if_success():
try:
self.base_find_element(loc, timeout=2)
return True
except:
return False
如何区分正向逆向用例
思路:在测试数据中添加一一个标识正向用例或逆向用例的标记: 如:True/False
步骤:
1. 调用登录方法(此登录方法中,只有输入用户名、输入密码、输入验证码、点击登录按钮) 切记:不要封装点击登录连接地址;
2. 判断是否正向用例:
# 判断安全退出是否存在
# 点击安全退出
# 点击登录连接地址