前言:该实例适合0基础同学,讲解RF代码实现功能自动化添加数据过程,有基础请直接略过1.1基础设置部分
本文主要涉及到2个页面:添加活动、设置奖品
1.添加活动
添加活动页面如下:
测试流程:进入添加页面-》点击“请选择关联活动”-》选择想要关联的活动-》确定
1.1 基础设置
1.1.1 创建工作目录,目录树结构大致如下:
1.首先创建一个Project类型(Type 选择Directory)输入项目名称,如 testScripts
创建成功后,选中项目右键创建“Suite”或“Directory”(一般项目包含的模块较多,建议创建该层级)
☀ “Suite”与“Directory”的区别:
Directory:作为目录,下方可以添加下级目录或Suite,但不能直接添加Test Case;
Suite:添加时可以选择类型(Type),当类型选择“Directory”时功能同Directory,选择“File”时可以在下方添加Test Case;
2.在project下方创建Directory 或Suite选择Directory类型:(可使用大的模块命名,根据需求层级不限)
3.创建File类型的Suite:(小模块或功能命名)
4.在Suite下方创建TestCase:
将自动化脚本写到Test Case中
1.1.2 导入库
选中Suite1️⃣后点击“Library”2️⃣输入需要导入的库名3️⃣即可,库名显示黑色表示导入成功,红色导入失败需要另外找原因
或者点击“Text Edit”并直接输入以下常用库:
Library Selenium2Library
Library Collections
Library RequestsLibrary
Library AutoItLibrary
Library Screenshot
Library XML
Library OperatingSystem
Library re
Library String
做完以上操作,基础就算准备好了,可以开始写脚本了!
1.2 代码实现
1.2.1首先登录写到user keyword:LOGIN 中,然后将LOGIN 放到suite的setup中
Login 中的脚本如下:
open browser ${login} gc
Maximize Browser Window
Page Should Contain 店店U惠管理总后台
sleep 1
input text //*[@id="app"]/div/div/section/form/div[1]/div/div/input 1395123123
input text //*[@id="app"]/div/div/section/form/div[2]/div/div/input 123
Click Element //span[text()='登录']
1.2.2 创建User Keyword:V 用于放相同类型不同值的全局变量
注意新版本不支持$需修改为@
定义的变量,随着开发过程可能出现增减;
在test case 的set up中引用V
1.2.3 添加test case 的内容实现功能
Login 进入页面后一般需要加载一会,所以第一行添加了sleep,因为wait until时不时就不生效
sleep 1
go to ${address}
${address}为要进入的地址,可以是最终地址也可以是大模块功能地址,此处进行了变量参数化
·●·点击进入编辑页面后,点击“关联活动”链接进入选择活动页面:
#点击编辑链接
Wait Until Element Is visible //tbody/tr/td/div[text()='${Cid}'] 10
click element //*[text()="编辑"]
#进入编辑页面
Wait Until Element Is enabled //*[text()="请选择关联活动"] 10
click element //*[text()="请选择关联活动"]
sleep 0.5
检查元素是否能被匹配可以使用firefox的开发者工具:
·●·接下来选择活动弹窗页面选择具体活动:
经观察此弹窗页面无查询模块不能根据查询匹配,列表可以根据ID进行关联选择,但如果当前页面未显示对应的ID,就需要翻页匹配。总结实现思路如下:
1.通过ID匹配到checkbox
Click element //*[text()="${ID[0]}"]/..//preceding-sibling::td[1]
- ${ID[0]}为V中设置的全局变量${ID}的第一个值(新版本定义为@{ID}),即需要添加的活动ID
- /… :取当前节点的上一层父节点,此处匹配到活动ID的父节点td
- preceding-sibling::td[1]:取当前节点的兄弟节点前的第一个td,即图中checkbox
2.处理翻页
思路:获取总页数作为循环次数,循环检查当前页面是否包含对应的活动ID,包含则选择活动并确定关闭弹窗
2.1 获取总页数思路:
1)直接获取总页数;
2)获取总数据,计算出总页数,每页对响应的ID进行匹配,匹配到ID后选择并退出页面;
方法一:根据右箭头定位,取最后一个分页的值li[last()]
${number} Get Text //*[@class="el-icon el-icon-arrow-right"]/../preceding-sibling::ul/li[last()]
方法二:(获取返回文本后截取部分内容,除以每页显示数量得值)
Wait Until Element Is visible //table[@style="width: 959px;"] 10
${text} Get Text //span[contains(text(),'共 ')] #获取总页数
${total}= Get Substring ${text} 2 4 #通过 Get Substring 截取文本中的数字
${number}= Evaluate ${total}/10.0 #总数/每页展示数
定义${number}为总页数,翻页数为总页数-1
${number} evaluate ${number}-1 #第一页不用点击
2.2 添加FOR循环:${INDEX}=0,${number}=9
: FOR ${INDEX} INRANGE ${number}
${element_exists} Run Keyword And Return Status Page Should Contain Element //*[text()="${ID[0]}"]
log ${ID[0]}
${page} Evaluate ${INDEX}+2
run keyword if ${element_exists} click element //*[text()="${ID[0]}"]/..//preceding-sibling::td[1]
... ELSE click element //li[text()='${page}']
sleep 0.5
Exit For Loop If ${element_exists}
- 通过Page Should Contain Element判断当前页面是否存在对应的ID,存在${element_exists} =True
- 默认显示第一页,故代码24行定义变量${page}将第二页的页码传给${page}
- 通过run keyword if 判断如果:${element_exists} =True,则点击checkbox,否则点击页码;
- 点击页码后等待页面加载0.5s
- 如果找到设置的ID则退出循环:Exit For Loop If ${element_exists}
2.设置奖品
设置奖品页面如下:
设置奖品页面输入的内容较多,通过“添加奖项”实现添加奖品数量,每个奖项共有6个可操作项。
相关脚本如下:
2.1 奖项数量控制
添加变量${num}控制奖品数量(也可放在V中定义),点击左侧目录树可单独设置num的值,图中为添加15个奖品
此例中循环15次${n}的值记录迭代次数:0~14
2.2 奖项值添加
定义变量${Pnum}获取当前赋值的奖项,赋值${n}+1
47行:为对该值的引用
2.2.1 奖项,下拉框:一等奖~十等奖
1.定义全局变量:在关键字V中定义全局变量${level},设置值为1~10等奖
2.定义变量${Lnum}设置需要设置的奖项
${level[0]}对应一等奖
由于奖品类型一共有5个(其中现金红包暂不添加),为了使一等奖包含所有奖品类型,进行以下操作
${value} Evaluate ${Pnum}%4
${Pnum}%4求余为0时Lnum+1,表示每个类型都添加过一个奖品了。
2.2.2 奖品类型,下拉框:五种类型
1.定义全局变量:在关键字V中定义全局变量${type},设置值为各类型名称
2.定义变量${Ptype}设置奖品类型:
${type[0]}对应优惠券,每次迭代后${Ptype}+1,第二次迭代${type[1]}对应积分:
A 奖品类型:优惠券
业务场景中设置奖品类型后,后续的4个可改项都与该类型关联,如下图:
为了现实每种奖品单独设置,采用自定义关键字的方法,通过Run Keyword If 判断是否满足条件,满足则执行,不满足不执行
当${type[${Ptype}]}=${type[0]}=“优惠券”时,执行关键字:Coupon-修改默认图片
关键字内容见下图,由于优惠券是默认显示的,此处略去了选择“奖品类型”部分内容
选择奖品:弹窗可查询
奖品分2大类,3种页面:根据奖品类型的不同,奖品列的值各不相同:
1 优惠券、兑换码、现金红包选奖品的方式一致,通过弹窗选择(取其一做解说)
2 积分为输入框方法
3 第三方渠道为弹窗手动输入方式
点击“请选择优惠券”弹出的弹窗页面如下:
分析该页面可通过优惠券编号查询后选择
1.定义全局变量:在关键字V中定义全局变量${couponID},设置值为各类型名称
2.定义变量${couponNum}设置需要设置的优惠券
input text //*[@placeholder='请输入优惠券编号/名称'] ${couponID[${couponNum}]}
sleep 0.5
send {enter}
sleep 0.5
Wait Until Element Is Visible //*[text()='${couponID[${couponNum}]}']/../../td[1]/div/label/span[1] 10
click element //*[@class='el-radio__inner']
输入待查询的优惠券ID,点击enter键查询并等待查询结果后点击单选框;
选择奖品图片
奖品图片都有默认值,可以修改,计划设置第一次添加该类型奖品不修改图片,后续再添加相同类型奖品修改图片,添加了一个循环判断是否满足第二次添加该奖项
点击当前迭代中对应的记录,删除默认图片后上传图片,等待2s(之前等待的时间较短,导致图片地址部分内容未成功输入)
此处上传的是网络地址,${img}在V中进行了定义,也可以在Suite中定义,或直接输入地址
☀ 如果网络地址较长会出现被截断的情况,此时只需将被截取的部分再次send即可,建议sleep0.1
选择图片后点击enter键确认上传,并等待2s加载显示;
追加奖品数量:输入框
输入框无特定要求默认设置100,未进行参数化
#输入追加奖品数量
input text //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[8]/div/div/div/div/div/input 100
用户限领
设置每人限领10份:
完成奖品设置后${couponNum}的值+1,第二次遇到相同类型奖品时,取第二个优惠券ID,同时对奖品图片进行修改,需在关键字“Coupon-修改默认图片”中定义全局变量:(否则test case 迭代会被重置)
#选择优惠券
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[3]/div/div/div/div/a/span #展开选择奖品弹窗
Wait Until Element Is Visible //*[@placeholder='请输入优惠券编号/名称'] 10
input text //*[@placeholder='请输入优惠券编号/名称'] ${couponID[${couponNum}]}
sleep 0.5
send {enter}
sleep 0.5
Wait Until Element Is Visible //*[text()='${couponID[${couponNum}]}']/../../td[1]/div/label/span[1] 10
click element //*[@class='el-radio__inner']
#修改优惠券图片
: FOR ${INDEX} IN RANGE 1
Exit For Loop If ${couponNum}==0
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[5]/div/div/div/div[2]/div/div/i #删除原图片
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[5]/div/div/div/div[1]/div/div/div/em #点击上传图片
sleep 2
#send ${img}\/challenge\/game\/lotteryCoupon0\.png #上传默认图片
send ${img}\/657c1fbf340d390396b3f8e97da62d69 #上传非默认图片 https://img.chinamallsales.com/
send {enter}
sleep 0.1
send {enter}
sleep 2
#输入追加奖品数量
input text //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[8]/div/div/div/div/div/input 100
#用户限领
input text //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[10]/div/div/div/div/div/input 10
Set Global Variable ${couponNum} ${couponNum}+1
B 奖品类型:积分
当${type[${Ptype}]}=${type[1]}=“积分”时,执行关键字:Integral-修改默认图片
关键字内容见下图
经过观察发现,奖品类型下拉框有2种展现方式:
因此在选择奖品类型时添加了一个对下拉框属性的判断:“bottom-satrt” or “top-start”
${Award-TS} Run Keyword And Return Status Element Should Be Visible //*[@class="el-select-dropdown el-popper"][@x-placement="bottom-start"]
run keyword if ${Award-TS} click element //*[@x-placement="bottom-start"]//*[text()="${type[${Ptype}]}"]
... ELSE click element //*[@x-placement="top-start"]//*[text()="${type[${Ptype}]}"] #选择奖品类型
添加奖品:输入框
希望积分与奖品挂钩,不同的奖品积分不同,故添加了一个For循环,判断当前奖项与迭代的奖项相同时,将迭代次数作为奖品进行设置:
此处值:${INDEX}+1,可以另外定义一个变量-1来实现奖项越小奖品越大,如:一等奖=10,二等奖=10-1=9
其他同优惠券不再细说。
#选择奖品类型
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[2]/div #展开奖项类型下拉框
sleep 0.5
${Award-TS} Run Keyword And Return Status Element Should Be Visible //*[@class="el-select-dropdown el-popper"][@x-placement="bottom-start"]
run keyword if ${Award-TS} click element //*[@x-placement="bottom-start"]//*[text()="${type[${Ptype}]}"]
... ELSE click element //*[@x-placement="top-start"]//*[text()="${type[${Ptype}]}"] #选择奖品类型
#判断积分奖励
: FOR ${INDEX} IN RANGE 9
${element_exists} Run Keyword And Return Status should be equal ${level[${Lnum}]} ${level[${INDEX}]}
${points} run keyword if ${element_exists} Evaluate ${INDEX}+1
Exit For Loop If ${element_exists}
#输入奖励积分
input text //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[3]/div/div/div/div/div/input ${points} #输入奖励积分
#修改积分图片
: FOR ${I} IN RANGE 1
Exit For Loop If ${intergralNum}==0
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[5]/div/div/div/div[2]/div/div/i #删除原图片
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[5]/div/div/div/div[1]/div/div/div/em #点击上传图片
sleep 2
#send ${img}\/challenge\/game\/lotteryPoints0\.png
send ${img}\/99cbb59ec40470b2d9ded4cea2c11d94 #上传非默认图片
send {enter}
sleep 0.1
send {enter}
sleep 2
#输入追加奖品数量
input text //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[8]/div/div/div/div/div/input 100
Set Global Variable ${intergralNum} ${intergralNum}+1
C奖品类型:第三方渠道(设置奖品)
点击“设置奖品”可进入第三方渠道奖品页面,此弹窗页面主要是有一个跳转类型需要注意:
这里同样使用关键字的方法设置:
#输入第三方渠道
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[3]/div/div/div/div/a/span #展开选择奖品弹窗
Wait Until Element Is Visible //*[text()='奖品名称']/../div/div/input 10
input text //*[text()='奖品名称']/../div/div/input ${level[${Lnum}]}${Cid}-${ID[0]}店店U惠 #输入奖品名称
input text //*[text()='页面路径']/../div/div/input v2/pages/goods/gooods?id=1239 #输入奖品路径
Comment #选择跳转类型
Comment click element //*[text()='跳转类型']/../div/div/div/input
Comment sleep 0.5
Comment #选择其他小程序
Comment Wait Until Element Is Visible //body/div[4]/div/div[1]/ul/li[2] 10
Comment click element //body/div[4]/div/div[1]/ul/li[2]
Comment sleep 0.5
Comment input text //*[text()='页面路径']/../div/div/input inside/pages/taskDetail/index?taskId=2
Comment input text //*[text()='appID']/../div/div/input wxb0296740b23541e9
Comment #选择H5
Comment Wait Until Element Is Visible //body/div[4]/div/div[1]/ul/li[3] 10
Comment click element //body/div[4]/div/div[1]/ul/li[3]
Comment input text //*[text()='页面路径']/../div/div/input https://sz-store-h5.chinamallsales.com/littleGameGroup/index/b1d5f0f4b355aa11
click element //*[text()='确定']
第三方渠道设置脚本:
#选择奖品类型
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[2]/div #展开奖项类型下拉框
sleep 0.5
${Award-TS} Run Keyword And Return Status Element Should Be Visible //*[@class="el-select-dropdown el-popper"][@x-placement="bottom-start"]
run keyword if ${Award-TS} click element //*[@x-placement="bottom-start"]//*[text()="${type[${Ptype}]}"] ELSE click element //*[@x-placement="top-start"]//*[text()="${type[${Ptype}]}"] #选择奖品类型
#输入第三方渠道
run keyword if "${Jtype[${CNum}]}"=="其他小程序" JumpType-other
run keyword if "${Jtype[${CNum}]}"=="店店U惠" JumpType-DDUH
run keyword if "${Jtype[${CNum}]}"=="H5" JumpType-H5
LOG Jtype is ${Jtype}
#修改奖品图片
:FOR ${INDEX} INRANGE 1
Exit For Loop If ${CNum}==0
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[5]/div/div/div/div[2]/div/div/i #删除原图片
click element //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[5]/div/div/div/div[1]/div/div/div/em #点击上传图片
sleep 2
#send ${img}\/challenge\/game\/exchange0.png #上传默认图片
send ${channelImg[${CInum}]}
#send ${img}\/fffdccce5cbf2038a4d72742e01a020b #上传非默认图片
send {enter}
sleep 0.1
send {enter}
sleep 2
#输入追加奖品数量
input text //*[@class="el-table el-table--fit el-table--border el-table--enable-row-hover el-table--enable-row-transition"]/div[3]/table/tbody/tr[${Pnum}]/td[8]/div/div/div/div/div/input 100
Set Global Variable ${CNum} ${CNum}+1
run keyword if "${CNum}"=="0+1+1+1" Set Global Variable ${CNum} 0
Set Global Variable ${CInum} ${CInum}-1
3.运行脚本
脚本写好后点击F8或开始图标可以执行脚本
执行结果会自动在run中显示:
执行完后可以通过log查看日志详情:/log.html