1. 测试框架介绍
概念:可以把框架看做是一个半成品的工具,介于工具和原生代码之间,用户在使用的时候需要二次开发调用封装之后才能使用。
工具:postman、soapui、jmeter、badboy、fiddler、charles
框架:selenium、appium、flask、pytest、DDT、KDT、POM、RF
2. 框架的好坏标准
独立于测试工具、测试步骤可重用、测试资产可重用(测试脚本,测试数据,测试环境)、测试数据易定制、异常处理机制、测试脚本易开发、测试脚本易维护、无人干预执行、代码可移植性高、适宜于团队开发
3. 基础框架分层
基础代码层:实现一些核心业务的基础脚本
数据管理层:存放脚本中用到的测试数据、参数化脚本、测试用例
调度管理层:用于实现脚本调用
4. 分层思想的设计指导原则
上层总是依赖下层,不要夸层访问
一切从系统需要提供的功能进行分析
每个层的接口有明确的职责范围
只要接口规范无变化,接口的实现就互不影响
5. 主流的框架设计思路
数据驱动(data driver testing, DDT):将测试数据跟测试脚本相互分离,对于框架的使用者来说只需要维护外部数据,不需要关注脚本实现,通过数据来驱动脚本执行
关键字驱动(keywords driver testing, KDT):将测试数据跟测试脚本相分离,关注的测试数据包括:测试动作、测试对象、测试数据,通过类反射机制实现测试动作跟脚本中封装的方法之间的映射进行方法的调用
6. Robot Framework介绍
Robot Framework是一款python编写功能自动化测试的框架。具备良好的可扩展性,支持关键字驱动,可以同时测试多种类型的客户端或者接口,可以进行分布式测试执行。主要用于轮次很多的验收测试和验收测试驱动开发(ATDD)。
7. Robot Framework特性
1)易于使用,采用表格式语法,统一测试用例格式;2)重用性好,可以利用现有关键字来组合新关键字;3)支持变量;4)支持创建基于数据驱动的测试用例;5)结果报告和日志采用HTML格式,易于阅读;6)提供标签以分类和选择被执行的测试用例;7)平台、应用无关;8)功能全面,支持web测试,java gui测试,启动线程,终端和SSH等;8)易于扩展,提供了简单的API,用户可以自定义的基于python或者java的测试库;9)易于集成,提供了命令行接口和基于XML的输出文件;10)易于与版本管理集成(Jenkins)
8. Robot Framework安装部署
pip install robotframework==3.2.1 --安装RF环境
pip install wxpython==4.0.7.post2 --安装RF工具ride需要的界面库
pip install robotframework-ride==1.7.4.2 --安装RF的脚本编辑工具ride
pip install robotframework-selenium2library==3.0.0 --安装RF的selenium关键字库
pip install robotframework-requests --安装RF的requests关键字库
安装好之后,如果桌面没有ride快捷方式,则到python的Scripts文件中运行python ide_postinstall.py,如果显示 not found from robotide import main,建议全部卸载上述安装库,然后自动安装最新版本。(这个问题我也是遇到很多次)
9. RF基本使用方法
文件创建:点击file--点击New Project
测试套件创建:右击创建的文件,选择new suite
10. RF的变量定义
普通变量
如果遇到 'Output' object has no attribute '_xmllogger'的问题,将Robotframework版本改为6.1.1
列表变量
定义列表时有@{变量名}和${变量名} ,使用@时,将列表看成一个个元素的组合,不能使用log打印,要使用log many,且打印时一个个打印;使用$时,将列表看成一个整体,可以使用log打印
字典变量
与list变量定义方法类似,有&和$两种定义方式,打印时,建议使用log many
常量
RF提前订好的变量,定义之后不会在发生变动,${EMPTY} ${SPACE} ${None} ${True} ${False}
11. RF常用快捷方式
F5:打开RF的关键字搜索框
ctrl+alt+空格:关联关键字
ctrl+shift+i:在选中的单元格前面加一个单元格
ctrl+shift+D:删除选中的单元格
crtl+i:在当前单元格上方插入一行
ctrl+d:删除这一行
F8:运行脚本
ctrl+3:注释脚本
ctrl+4:取消注释
12. RF常见关键字
${变量名}:普通变量定义
log:输出普通字符串
long many:输出序列的值,输出多个值,也可以输出一个值
set variable:设置普通变量
create list:设置列表
create dictionary:设置字典
13. RF基础控制结构
分支结构:
循环结构
14. RF构建关键字
步骤:右击文件夹--选择New Resource--右击选择New User Keyword
作用:像python中定义的函数def,可以通过输入对应参数进行调用
15. UI自动化
首先需要导入包(注:导包是在套件里导),导包正确字体是黑色,不正确是红色
但是程序如果存在错误时,会无法执行之后的关闭浏览器的指令,所以关闭浏览器加入套件后置中
其他关键字:
下拉框选择 select from list by value 元素定位方式 元素名称
JS注入:execute javascript document.getElementById(...).value='....'
异常处理:${bool} run keyword and return status element should be enabled 元素定位方式
run keyword if ${bool} click button 元素定位方式
16. 数据库断言
下载databaselibrary库:pip install robotframework-DatabaseLibrary
可以设置书库据的查询操作设置返回值,通过返回值来判断是否存在对应信息
17. RF的接口测试
使用RF进行接口测试,与使用python的requests库进行接口测试差不多,测试前需要安装robotframework-requestslibrary
需要注意的是,当使用post时用data或者json传递参数,使用get时使用params传递参数
想要上下关联session,可以选择在登录时返回session,可以在下一次请求之时,带上上一次的cookie
18. RF数据驱动实现
方式一:模板实现数据驱动,对关键操作进行封装,然后就可以在一个suite中多次使用,类似于把suite表格当成excel文件使用
方式二:excel实现数据驱动,首先要安装robotframework-ExcelLibrary,然后利用for循环从表格中读取数据与封装好的操作进行关键字传参,达到数据驱动的效果
19. RF自定义关键字
函数自定义关键字:1)在RF脚本的目录下新建一个目录用来保存python脚本;2)在目录中新建python脚本,自定义要实现的函数;3)重启RF,在脚本的第三方库层级中导包(可以用绝对路径,也可以用相对路径);4)导包之后直接在脚本中调用封装的关键字
类自定义关键字:1)脚本必须存放在python的lib目录中的site-packages文件夹中(下载的库文件,模块,类);2)脚本名必须跟类名重名,命名规范统一使用大写字母,不出现中文
20. 鼠标键盘事件PyuserInput使用
使用pymouse模拟鼠标事件
使用pykeyboard模拟键盘事件
常见的API:
鼠标操作:pymouse.click(x,y,button,n):xy表示坐标位置,button=1表示左键,=2表示右键;n表示点击次数默认为1
pymouse.move(x,y):鼠标移动到坐标(x,y)
x,y = pymouse.screen_size():获得屏幕尺寸
键盘操作:k.type_string('s'):模拟键盘输入字符串
k.press_key('S'):模拟键盘按住S键
k.release_key('S'):模拟键盘松开S键
k.tap_key('S',n=2,interval=5):模拟键盘敲击S键,n=2表示敲两次,interval=5表示每次间隔5秒
k.tap_key(k.function_key[5]):敲击功能键F5
k.tap_key(k.numpad_key[5],n):敲击小键盘5,n表示次数
联合模拟:
k.press_key(k.alt_key);k.tap_key(k.tap_key);k.release_key(k.alt_key):表示同时按alt+tab键
21. 图像识别(个人感觉意义不大,了解就行)
作用:一般使用selenium或者appium都会采用页面元素属性定位的方式,但不是所有的页面元素都能够正常定位,有时候会碰到不能正常定位的现象,这个时候就得使用其他的测试技术来解决自动化测试问题,图像识别就是其中一个技术。
图像识别的三个步骤:模板匹配,滑动对比,匹配相似度
模板匹配:将目标图片进行截取,截取的图片就是模板,那这个模块在在原图片上根据模板匹配方式去寻找图片对应位置,找到之后返回图片的中心点坐标,这个匹配过程就是模板匹配。
滑动对比:就是将目标图片从原图片的0,0像素点的起始位置开始便利横坐标以及纵坐标上的每一个像素点,整个遍历的过程就是滑动,在滑动的过程中会去对比模板图片跟目标图片所在位置的像素点。整个对比像素点的过程就是滑动对比。
匹配相似度:就是模板图片的所有像素点跟目标图片所在位置的像素点匹配成功的像素点的百分比,就是匹配相似度。
使用图像识别,需要安装pillow和opencv-python库
22. 持续集成
概念:持续集成(CI)是一种软件开发和测试实践,旨在通过频繁地将代码集成到共享代码仓库,并自动构建、测试和发布软件,从而提高开发团队的协作效率和软件质量。
优点:1)快速发现错误,每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易;2)防止分支大幅偏离主干,如果不经常集成,主干又在不断更新,会导致以后集成难度变大,甚至难以集成。
23. SVN版本控制工具
版本控制主要是利用一个中央代码仓库集中统一管理代码的版本,研发团队随时提交的任意代码和变更均会以版本号进行记录,并且可以防止代码版本不同步的情况。在团队开发中起到了非常重要的作用,可以避免很多代码冲突,版本不一致等情况,当然,也为持续集成提供了技术基础。
SVN和GIT的区别:
1)GIT是分布式的,SVN是集中式的
2)GIT把内容按元数据方式存储,而SVN是按文件:因为git目录是处于个人机器上的一个克隆版的版本库,他拥有中心版本库上所有的东西
3)GIT的内容完整性优于SVN,GIT内容存储使用的是SHA-1哈希算法,这确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
4)GIT适用于单一项目的开发版本管理,SVN适用于多个项目同时并发执行
5)GIT适用于项目团队成员比较多,比较分散,不在同一个区域办公,SVN适用于一些初创的团队,团队成员都在一起办公。
24. SVN使用
1)新建项目
然后一直点击下一步,最后结束完成时,会返回一个URL地址
2)可以自己创建用户,右击User,选择create user
3)在自己电脑本地新建一个文件夹,用于连接SVN服务器,进入文件夹右击,选择svn checkout,设置对应路径
4)上传文件到svn,右击选择svn commit,如果想从服务器拉取文件,选择svn update
25. SVN常见的命令行操作
1)svn checkout svn://路径 本地路径 --username 用户名 --root 密码 :表示第一次从服务器中检出源码
2.)svn update 本地路径:表示第一次从服务器更新源码
3)svn add test.php:表示在本地添加新文件
4)svn commit -m ‘添加测试用的test.php’:表示将本地的新文件上传到svn服务器
注:要使用svn命令,需要将svn所在的bin目录添加到环境变量中
26. Python实现持续集成
1.下载源码,使用SVN来下载:os.system(svn update/svn checkout)
2.构建版本,使用版本构建工具:ANT
ant是一个基于java项目版本构建的一个自动化工具,直接在apache官网上下载
要使用ant命令来构建版本,需要配置环境变量:将ant的bin目录加到path路径中
使用ant -f build.xml:xml(可扩展标记语法)与html(超文本标记语言)都是属于通用标记语言的子类,都有共同的特性,都是有标签,属性,属性值来描述文档的,html的标签是定义好的,xml的标签都是自定义的,用来记录文件数据的。
3.部署项目环境
1)windows删除文件(但保留文件夹):del /S /Q names:/S表示递归删除,/Q表示安静模式删除,没有提示
2)windows删除目录:rd /S /Q 目录路径
3)windows复制文件:copy source destination
4)启动tomcat:os.system('startup.bat')
5)关闭tomcat:os.system('shutdown.bat') os.system('start /b taskkill /F /IM java.exe')
6)修改配置文件:使用open函数直接打开配置文件,重新替换一份新的配置文件信息
4.调用自动化测试脚本进行测试
通过命令调用python脚本
将脚本完整的路径加载搭配python运行环境中:set PYTHONPAHT=文件夹路径
切换到测试脚本所在目录
调用python解释器执行脚本文件:python 脚本名
5.使用yagmail发送邮件
27. 代码示例
import os
import time
import yagmail
class MyCi:
def __init__(self):
self.svn_client = 'dirname'
self.svn_server = 'remote dir'
self.tomcat_path = 'tomcatpath'
#下载源码
def svn(self):
print('当前正在执行源码下载操作,请稍后....')
dir_li = os.listdir(self.svn_client)
if len(dir_li)==0:
os.system('svn checkout {} {} --username root --password 123456'.format(self.svn_server,self.svn_client))
else:
os.system('svn update {}'.format(self.svn_client))
print('源码下载完毕!!!')
#构建版本
def ant(self):
print('当前正在构建版本,请稍后....')
if os.path.exists('{}\\build.xml'.format(self.svn_client)):
os.system('ant -f {}\\build.xml'.format(self.svn_client))
else:
print('当前没有build.xml文件,请检查源码中是否具有该文件!!!')
print('新版本构建结束!!!')
#部署项目环境
def tomcat(self):
print('当前正在执行项目环境部署....')
os.system('start /b taskkill /f /im java.exe')
li = os.listdir(self.tomcat_path)
if 'dirname.war' in li:
os.system('del /S /Q {}\\webapps\\dirname.war'.format(self.tomcat_path))
time.sleep(1)
if 'dirname' in li:
os.system('rd /S /Q {}\\webapps\\dirname'.format(self.tomcat_path))
os.system('copy {}\\dirname.war {}\\webapps'.format(self.svn_client,self.tomcat_path))
#修改配置文件
while True:
if os.path.exists('{}\\webapps\\dirname'.format(self.tomcat_path)):
break
time.sleep(5)
os.system('{}\\bin\\shutdown.bat'.format(self.tomcat_path))
content = '''
配置信息
'''
with open('{}\\webapps\\dirname\\配置文件路径'.format(self.tomcat_path),'w',encoding='uft8') as f:
f.write(content)
os.system('{}\\bin\\startup.bat'.format(self.tomcat_path))
time.sleep(3)
print('项目环境部署完成!!!')
#调用测试脚本
def start_test(self):
print('当前正在调用测试脚本执行自动化测试....')
'''调用已经编写好的自动化测试脚本'''
print('测试脚本已经执行结束!!!')
#发送邮件
def email(self):
con = yagmail.SMTP(user='',password='',host='')
with open('report_path',encoding='uft8') as f:
content = f.read()
os.system('rar a 压缩之后路径和文件名 需要压缩的文件夹1 文件夹2')
attachment = '压缩之后的文件名'
con.send(to='',subject='title',contents=content,attachments=attachment)
#执行
def main_test(self):
self.svn()
self.ant()
self.tomcat()
self.start_test()
self.email()
#持续集成
def start_ci(self):
#轮询
# while True:
# self.main_test()
# time.sleep(60*60*24)
#指定脚本执行时间
# while True:
# H = time.strftime('%H')
# if H=='00':
# self.main_test()
# time.sleep(3601)
#只要开发提交版本就调用持续集成
while True:
print('当前正在检测版本有没有更新....')
re = os.popen('svn update {}'.format(self.svn_client)).read()
if 'Restored' in re:
print('检测到版本更新,调用持续集成脚本....')
self.main_test()
continue
time.sleep(3)
print('当前库没有更新')
28. Jenkins 安装及使用
概念:Jenkins是一个广泛用于[持续构建]的可视化web工具,就是各种项目的的“自动化”编译、打包、分发部署,将以前编译、打包、上传、部署到Tomcat中的过程交由Jenkins,Jenkins通过给定的代码地址,将代码拉取到jenkins宿主机上,进行编译、打包和发布到web容器中。Jenkins可以支持多种语言(比如:java、c#、php等等),也兼容ant、maven、gradle等多种第三方构建工具,同时跟市面上的主流版本控制工具git、syn无缝集成,也支持直接与github直接集成。https://www.baidu.com/link?url=LZCSotY4V4nnACYSc_CIsVX3oubc-l80urG3DqE2RMjcD9A--O6lNmf7yGxzzSqDgoqoAXjGGDkSF3u7J_a96q&wd=&eqid=ab477b6e0072b39b0000000466c692ed
使用大致流程:
1)先登录jenkins,使用创建的账号密码登录
2)在Manager Jenkins中可以下载所需的插件,也可以配置全局信息
如果在安装插件时发现安装速度太慢,可以去高级设置中修改升级站点,使用国内的镜像源,同时也可以自己去下载了hpi文件,然后进行上传
3)全局配置需要配置相关JDK和ANT,如果忘记了jdk的目录,则在cmd中where java 查询
4)新建项目,点击新建item按钮,默认freestyle project
5)进行项目的配置
6)如果想要配置测试脚本的运行时间,则需要构建触发器
7)构建环境,选择全局变量中设置的ant和jdk
8)新增构建,使用involve ant来构建版本
9)如果想要完成项目的部署,则新增execute windows command
10)关于邮件发送的发方法,可以直接在python文件中进行编写,可以使用jenkin插件来进行。首先要进入system configuration设置项配置email,然后找到jenkins location,完成系统管理员邮件地址的填写,然后去邮件通知部分配置信息,进一步去extend email配置信息(需下载插件),最后去项目中配置构建后文件,设置邮件发送触发器,选择advance settings,配置add trigger