Web自动化框架-selenium
一、八种单数:(就够用了)
id
class
tag_name
linktext
包含定位
xpath(第二种选择)
所以写的方式:=driver.find_element_by_xpath('//input[@placeholder="请输入账号"]').send_keys('admin')
css(第一种选择)
name
二、八种复数(暂时用不到)
三、2个底层(暂时用不到)
四、三种切换
tab(浏览器产生了多个页签)
switch_to.window(handles[-1]) #取我们产生的最新的
switch_to.window(handles[0] ) #取第一个
close #如果你切换tab,时刻要close,用完一个标签,就要关掉
alert
确定
取消
iframe
当iframe没有id或name时,先定位到iframe这个标签
xxx.iframe(element)
当iframe有name和id时
iframe('name')
iframe('id')
iframe是将一对HTML标签嵌套另一对HTML标签,所以要求一层一层的切换,如果我切进去想外出,得一层一层往外出
default:默认到最外层
鼠标悬浮操作:
原理:每次通过一个匿名函数向一个数组中 添加一个未执行的函数,这个函数就是自己的操作,当你调这个perform,才统一去将case里所有运行
.perform()
js操作
dom语句,就一种,获取这个元素,将它的style属性中的display属性干掉,让他展示出来,我们再去操作
等待
time 调试时用
隐式 不考虑
显式 必须每次都用
显式用于网络超时不稳定的风险,这个显式就能规避
步长 0.5s
超时时间10s 10s里有20个0.5 每隔0.5s就问一次,相当于问20次,没有timeout的exception
如果写 case,遇到一个定位不到元素,排查:
1.分析HTML,看清楚哪些是我们要用的唯一属性
2.看清父子级关系
3.有没有浏览器的tab要切换
4.排查有没有iframe
5.排查这个元素在代码调用打开时,页面是否渲染了
6.排查你定位的元素是否有display属性 ,有的话,就被隐藏了,看不到
7.需要单独的把这个case拿出来,不用显示等待,用time调试方式,确保原始是可以点击
8.看你的操作是否需要连贯操作(特殊场景) 用到了action操作了
9.是不是我的定位方式写错了,没写错,按照1-8排查完还有问题,问一下开发,是否有特殊处理,如:js动态处理
封装pyse
五、Web自动化框架搭建及禅道项目实战
用到:1.我们基于selenium扩展封装+unittest进行case管理+核心思想及配置基于PageObject+Python+case和page分离+HTML报告+pyse
在文件夹中导入一个pyse.py文件
PO封装思想(PageObject):将一个页面抽象为类class方法,将页面能够操作的元素抽象成一个个的方法
比如,我将登陆整个页面作为一个类,然后用户名是def一个方法,密码def一个方法,保持登陆def一个方法,忘记密码def一个方法
登陆按钮def一个方法,简体def一个方法,这样这个页面封装便于维护,尤其前端改版
转换成代码:
然后将每个方法完善一下
1.先获取用户名的页面元素
先用pyse的css定位
不过pyse能用css定位,不要用其他定位方式
现在我们在写一个类,主要是封装一下公共的方法,大家都可以调用
为了能让后续的类能用到BasePage,如LoginPage,那么我就把BasePage让LoginPage继承一下
这样通过将LoginPage实例化,BasePage也可以用
然后如果多个页面都要调用BasePage,为了避免多个import,我可以再封装两个方法,分别直接继承LoginPage,和Menu
代码时自上而下执行,Menu继承LoginPage,Page继承Menu,这样执行Page类,其他的类就都被初始化了
下面应用一下
关注一下css定位和xpath定位
css需要#,xpath定位不需要
我再把密码和登录按钮的方法完善一下
PO思想熟悉了,我们开始维护case,框架开始了
接口是数据驱动,UI自动化是关键字驱动
首先创建几个目录,bin目录是启动目录,lib是我们的核心代码,page是存储配置,test_case是存储我们的case,report存储我们的结果,path是存储的环境变量
pyse.py应该放到lib目录下
page.py应该放在我的page目录下
case组成完成后不会变,为了保持case不动,所以要case与page分离,解耦
首先在test_case下创建文件test_zzbx.py
统一主入口,bin目录下创建一个run.py,现将HTMLTestRunner.py加到lib下,
path.py 放在lib目录下
如果让报告报错的截图保留下来,去HTMLTestRunner.py看一截图调用的哪个方法,应该是error_picture我需要在lib目录下创建一个tools.py
如果case执行失败了,报告中报错图片没有生成,不显示,现在解决一下
case过没过,怎么判断,比如登录,就是登录成功后,能见到退出,否则见不到
所以我们现在在page的LoginPage中增加一个方法 check_Login,检查登录是否成功,返回true或flase
然后再到test_zzbx.py中给login增加断言
在看截图
找到图片生成的路径,我们去path中添加一下,并且我们在report下 创建一个picture文件
我们打印一下
发现picture后面没有/, 无法写文件了,为了保证有/我们在report拼接一个空字符串
在打印一下
pyse.py中的保存截图方法
我们现在可以运行一下case错误的截图,测试失败就是定位元素写错一下就行
现在的问题是图片没显示出来,是因为名字写错了,思考这样一个问题
我们如果测试用例特别多的情况下,case只有一个pi文件,这一个pi文件下可能存在几十个或几个测试用例, 每个测试用例都有肯能失败
图片都放到一个路径下 ,怎么来规避这个图没有赋到错误的 用例上 ,有可能存在这个图片是两个用例失败了,这两个用例的图片串了
所以,这个判断逻辑在HTMLTestRunner中判断的
就是如果png_name==name 如果图片名称和case名称不相等,就不执行这个代码
case的名称
图片的名称
解决方案:在page中的check_Login中加个参数name,将123123去掉换成name
然后再将test_zzbx.py中的test_a_login这个名称当做参数传给check_login就可以了
通过以上操作就生成了以我们用例名为名的图片名
现在图片还是没有渲染出来,现在picture已经生成错误图片,如果想捞取一个文件下的所有文件,需要在tool下写提供图片的方法
并且我们自测一下
有个这个图片后,我们需要把他追加到列表picture中
打印一下结果:
效果图:
下面接着以禅道为例,我们写新建bug
首先,page.py中已经有一个Login了,我们再写几个页面,把每个页面当做I一个类
上面我们把bugl列表要使用的元素用了,现在再看新建bug页面
我们先获取所属模块,有三种方式(后期介绍),目前所属模块的属性很少,我们用它的父标签,id
下面在找到所属模块列表下的几个选项,点击操作
在page.py 操作
下面调试运行一下
下面进行进行影响版本,由于所属模块和影响版本使用的css一样,为了避免重复,我们优化一下
下面是影响版本的获取
下面调试运行下page.py
效果:
取所属模块的另一种方法(直接有下拉框):我们发现,点击所属模块应该是下拉框,其实就是select的name=module,这是真正跟后台交互的
但由于有style=display属性,所以不显示,我想让他显示,就必须加上宽高属性,并将style属性为空
下面解决有下拉框直接选css取值
使用doc命令,已知一个id是module,style的属性display去掉
鉴于上图,我们要执行的语句其实就是3,所以在page.py,在NewBug类中加个模块2的方法
调试运行一下,我们把page.module()和version替换成page.module_select()
同理也可以把影响版本使用js的doc命令方式去写
现在写一下截止日期,HTML如下
bug类型,HTML
写操作系统,HTML
写浏览器,HTML如下
写当前指派,HTML如下
这个跟所属模块一样,我们按点两次操作
下面写标题,HTML如下
所有调试运行一下
下面开始重现步骤
保存操作,由于重现步骤输入框iframe已经改变,需要向上跳一层,封装一个方法
如果是小屏幕的电脑,保存按钮可能需要滚动条一下,用doc命令
save方法需要加一条
我们再说一下iframe这个问题,我们刚才是按自上切iframe取到的,现在也可以去定位某个元素,去掉display=none属性,然后在操作这个textarea,这样就不用切一次iframe,本身就在iframe外面
在page.py中写
由于save方法是在没有切换写的,所以我没在写个save2方法
page.py中修改一下这两个save方法
将case挪到case文件test_zzbx.py中
假设验证创建bug这个按钮是否出现
在page中封装一个方法
然后在case文件test_zzbx.py中校验一下
换一种校验方式:我检验bug列表有这个bug标题,但由于数据会分页,所以我要清一下自动化环境,保证只有一条数据
要清cleardb,可以在BasePage里写
如果业务场景有删除功能,走业务的清洗
下面进行bug标题验证,bug标题是个a标签
在page.py再写个check
运行为True,说明这条case成功
再用指派人校验(使用复数)
验证码问题:
1.拖动的,复杂,暂不考虑
2.数字验证码
a.要求开发给你个万能验证码或者或者万能账号不校验不判断验证码
b.开发给个这个账号对应的万能验证码
c.不求开发
页面上的验证码,开发怎么判断你写的验证码与他库里写的是正确的,他有个地方存储,当你登录,你拿着一个标识问后台,他拿这个标识再去别的地方取
取出来的和你传的一样说明通过了,取得过程他能取我们也可以取
举个例子,开发会在你的前端页面种个cookie,这个cookie是会携带着登录过去,根据cookie拼成一个串去redis取缓存