本文章介绍通过实现分利宝app部分功能自动化测试,来介绍Appium+python自动化测试app的基本原理和操作技巧,及坑点和个人经验,来帮助想学习自动化测试的同学更容易地掌握相关技术。
首先让我们把环境搭建起来先:
(一)环境搭建
1需要jdk1.8版本或以上:
去官网下载对应版本,安装后配置环境变量。。。。。。此部分过于基础,不多讲。记住要1.8版本或以上就行!
2安装sdk:
官网(可翻墙选择):http://developer.android.com/sdk/index.html
不可翻墙选择:http://www.androiddevtools.cn/
下载这个即可:
下载后打开F:\android SDK\SDK Manager,按默认推荐安装SDK即可
配置环境变量:
增加ANDROID_HOME系统变量为你的android SDK路径,并把tools和platform-tools两个目录加入到系统的Path路径里。
例:ANDROID_HOME 变量值: F:\android SDK
配置完环境后,可以在运行cmd后输入 adb(能看到当前版本号),再输入android(空格)-h
以下是配置成功的截图:
3安装python:
官网或百度下载python下载好后安装到所需安装路径。
环境变量可以在安装过程中选择Add python to environment variables,安装后会自动配置环境变量
cmd输入python,出现版本号,配置成功:
4安装nodejs
进入地址并下载nodejs6.9.4的安装程序或包:http://ju.outofmemory.cn/entry/296682
此处注意,nodejs官网最新版是10.16.0,和本人下载的appium1_4_16_1版本不兼容(不兼容使用appium将会出现问题)。所以在上面的网址下载6.9.4的旧版本
下载安装完成后,运行cmd,输入node(空格)-v查看版本号:
5安装appium
进入官网地址:https://bitbucket.org/appium/appium.app/downloads/,并下载1_4_16_1版本即可:
appium安装好后:
找到这个文件安装目录F:\Appium\node_modules.bin,将上面的地址添加到环境变量path下;
打开cmd,输入appium(没有空格)-doctor,检查环境是否OK,出现All Checks were successful,说明环境OK
6安装Appium-Python-Client
此处Appium-Python-Client的安装网上大多数教程都是推荐用cmd 输入:pip install Appium-Python-Client,通过Python安装或直接去下载包。
这里因为我是使用pycharm来编程,所以直接用pycharm去下载安装。方法很简单,百度下载安装pycharm,激活pycharm(百度有教程)。
在File-Setting里找到Project Interpreter:然后点击+号,搜索Appium-,即可找到Appium-Python-Client,选中点击install package下载安装
(二)使用工具基本说明
1使用Appium:
如下图,左上方安卓按钮是配置手机信息,右上方三角按钮是启动Appium,右下方垃圾箱是清空Appium日志。
配置手机信息:选中Application Path,点击Choose,选择要测试的apk安装包(需要下载保存在电脑上)。选择后会自动填写Package,Wait for Package,Launch Activity,Wait for Activity(Package和Activity用于启动app)。Platform Name选择Android,Automation Name选择Appium,PlatformVersion选择不高于已安装的SDK,这里选择最新的API Level 23即可。Device Name输入已连接电脑的手机的ID:查看手机ID的话使用cmd输入adb devices即可
注:(如果因为没有安装驱动报错,则下载一个91手机助手连接手机就会自动安装驱动)
注:关于Appium获取打开手机app目前亲测发现只有通过Application Path去Choose一个apk才有效。网上介绍的使用cmd命令去获取Package和Activity并写入python的编程代码中去启动app并没有效果,会一直闪退无法进入app。(个人发现只要Appium Choose了apk,python代码不用写入Package和Activity也能打开app正常执行代码)
2使用uiautomatorviewer:
android SDK/tools/目录下有一个uiautomatorviewer工具,用于手机app界面的元素定位。手机正常连接电脑后,打开uiautomatorviewer点击左上角的安卓按钮,获取手机当前显示的静态屏幕界面。鼠标悬停在任意可点击的应用,右方会自动展示对应的定位元素信息;通常定位元素的class或resource-id,然而有些界面是无法定位到元素的,这时候就需要用到TouchAction坐标定位(后面进行详解)
3使用真机调试:
本文章介绍的是使用android手机进行自动化测试,由于uiautomatorviewer兼容性问题,android版本要低于8.0,否则获取手机屏幕会报错。我用的手机android版本是5.0.2;同时真机测试需要打开开发者模式和usb调试(操作很简单,不懂百度)
(三)Appium优点
1开源
2跨架构:NativeApp、Hybird App、Web App
3跨设备:Android、iOS、Firefox OS
4不依赖源码
5使用任何WebDriver 兼容的语言来编写测试用例。比如 Java, Objective-C, JavaScript with Node.js, PHP, Python, Ruby, C#, Clojure, 或者 Perl.
6不需要重新编译APP
(四)自动化测试实现
1启动测试环境分利宝app:
from appium import webdriver
from time import sleep
def equipmentMsg(self):
msg = {'platformName': 'Android', # 手机系统
'deviceName': '4S8DQS4T99999999', # 手机ID
'platformVersion': '5.0.2', # android版本
'noReset': 'true'}
Dr = webdriver.Remote("http://localhost:4723/wd/hub", msg) # 打开手机分利宝
Dr.implicitly_wait(10) # 设置隐性等待时间10秒
sleep(10)
return Dr # 返回driver
其中platformName,devicesName,platformVersion与上面的Appium配置一致,不解释。
注:noReset的用意是取消Appium每次运行app都要重新安装一次的机制,该参数也可以在Appium安卓配置种直接勾选;然后我在运行代码启动app时去掉noReset并未出现app重装现象,倒是会重复出现新手介绍的界面。因此我加上noReset来去掉新手介绍,直接进入app。
下方的webdriver.Remote("http://localhost:4723/wd/hub",msg)可以说是固定格式来启动app并返回一个driver = Dr(Dr在所有方法都有用到),用driver设置隐性等待时间10秒,implicitly_wait(10)
注:由于手机android兼容性问题,使用Appium操作真机会重复地要求安装Appium Setting和Unlock,解决这个问题只要到Appium安装目录F:\Appium\node_modules\appium\lib\devices\android下,编辑android.js,注释以下四行代码即可
2注册测试环境分利宝账号:
from Database import DBconnect
def signMsg(self, Dr, phone, ID): # 注册模块
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_phoneNum").send_keys(phone) # 输入手机号
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_getVerifyCode").click() # 点击获取验证码
sleep(2)
msg = str(DBconnect.DBconncet().searchYzm(phone)) # 查询手机号获取的验证码
yzm = "".join(msg.split(',')[2].split(':')[1].split("'")[1]) #分裂出sql中的验证码
print(yzm)
sleep(1)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_verifyCode").send_keys(int(yzm)) # 输入验证码
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_password").send_keys("123456") # 输入登陆密码
sleep(1)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/btn_submit").click() # 提交
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_right_label").click() # 跳过设置手势密码
sleep(6)
简单的点击和输入(括号里的id就是uiautomatorviewer获取的resource-id)
其中查询验证码:msg = str(DBconnect.DBconncet().searchYzm(phone)),是连接测试环境数据库获取新注册手机号发送的随机验证码并将数据库list数据裂解为纯数字字符串yzm = "".join(msg.split(',')[2].split(':')[1].split("'")[1])
查询数据库代码如下:
import pymysql
import os
def searchYzm(self, phone):
# 连接数据库
connection = pymysql.connect(host='xxx.xxx.xx.xxx', user='root', password='xxxxxx', db='xxx',
port=3306, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
# 通过cursor创建游标
cursor = connection.cursor()
# 创建sql 语句,并执行
sql = "SELECT * FROM xxxxxxxxxx where phone_num = " + str(phone)
cursor.execute(sql)
# 查询数据库单条数据
# result = cursor.fetchone()
# print(result)
# connection.commit()
# 查询数据库多条数据
result = cursor.fetchall()
for i, j in enumerate(result):
if i >= len(result) - 10:
print(j) # 遍历输出查询数据
return j
connection.commit()
connection.close()
这里len(result) - 10是查询后只展示最后10条数据,可用于查询数据量大的情况,由于sql里面用的查询条件是具有唯一性的手机号码,所有展示10条数据在这里没有体现出来。若只展示单行数据,也可以使用上方被注释的查询数据库单条数据的代码
再补充一个自动生成随机手机号方法:
def creatPhone(self):
head = "13,14,15,16,17,18,19"
body = str(random.randint(100000000, 999999999))
team = head.split(",")
phone = team[random.randint(0, len(team) - 1)]
num = int(phone + body)
print(num)
return num
3测试环境分利宝账号开户:
from appium.webdriver.common.touch_action import TouchAction
def openAct(self, Dr, phone, ID, cardNO): # 开户模块
commandP = 'adb shell ime set com.baidu.input_bbk.service/.PinyinIME' # 切换拼音输入法为当前输入法
commandA = 'adb shell ime set io.appium.android.ime/.UnicodeIME' # 切换appium输入法为当前输入法
rows = Dr.find_elements_by_id("com.fenlibao.fenlibao:id/et_content") # 遍历获取开户界面输入框元素
for i, j in enumerate(rows):
if i == 0:
j.send_keys("testman") # 输入姓名
sleep(1)
if i == 1:
j.send_keys(ID) # 输入身份证
sleep(1)
if i == 2:
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_bankName").click() # 选择银行卡
sleep(1)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_bankCard").click() # 选中银行卡
sleep(1)
os.system(commandP) # 切换输入法为本机输入法
sleep(1)
j.send_keys(cardNO) # 输入银行卡卡号
sleep(1)
os.system(commandA) # 切换输入法为Appium输入法
if i == 3:
j.send_keys(phone) # 输入手机号
sleep(1)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/bt_bind").click() # 确认
sleep(4)
TouchAction(Dr).tap(x=583, y=908, count=1).wait(2000).perform() # 点击获取验证码
sleep(2)
TouchAction(Dr).tap(x=360, y=808, count=1).wait(1000).perform() # 知道了
os.system(commandP)
TouchAction(Dr).tap(x=300, y=908, count=1).wait(1000).perform() # 点击一下验证码输入框
sleep(1)
ChonZhi.ChonZhi().tapYzm(Dr) # 输入验证码
sleep(1)
size = LoginApp.LoginApp().getSize(Dr)
LoginApp.LoginApp().swip(1000, Dr, size, 365, 1255, 365, 45) # 上滑屏幕
sleep(1)
TouchAction(Dr).tap(x=360, y=384, count=1).wait(1000).perform() # 点击一下交易密码
sleep(1)
ChonZhi.ChonZhi().tapPasswd(Dr) # 输入密码
sleep(1)
TouchAction(Dr).tap(x=360, y=498, count=1).wait(1000).perform() # 点一下确认交易密码
sleep(1)
ChonZhi.ChonZhi().tapPasswd(Dr) # 输入密码
sleep(1)
TouchAction(Dr).tap(x=345, y=738, count=1).wait(1000).perform() # 同意并注册
sleep(2)
注:开户过程中出现了输入银行卡号总是缺少一位数的情况,后面了解到是Appium输入法的bug,所以此处输入银行卡号需要切换输入法为本机拼音输入法commandP = 'adb shell ime set com.baidu.input_bbk.service/.PinyinIME';用os.system(commandP)执行切换(commandP的代码也可以在cmd使用),切换后点击输入框会出现软键盘,所以输入银行卡号后要重新切换会Appium输入法os.system(commandA),避免软键盘遮挡到界面元素
开户信息填写后要进入到新网界面进行验证和设置交易密码,这部分界面不属于分利宝app,要么无法获取元素ID,要么获取元素无法实现点击,输入等操作。这部分要用到前面(二)-2使用uiautomatorviewer有提到的TouchAction坐标定位
鼠标悬停在界面任意位置,右上方会有一个对鼠标指针进行定位的坐标。记录这个坐标使用TouchAction类方法实现对坐标位置进行点击,滑动等操作。如:TouchAction(Dr).tap(x=583, y=908, count=1).wait(2000).perform();(583,908)是获取验证码按钮的中心坐标,tap是触击,wait是指触击的时长(单位毫秒),perform是执行。其中还有一个getSize,swip获取屏幕大小,滑动屏幕的方法,也是调用TouchAction的方法我给封装起来,具体代码如下:
def getSize(self, Dr):
x = Dr.get_window_size()['width'] # 获取屏幕宽度
y = Dr.get_window_size()['height'] # 获取屏幕高度
return (x,y)
def swip(self, t, Dr, Size, x1, y1, x2, y2): # t是滑动的时间,毫秒
l = Size
X1 = int(x1)
Y1 = int(y1)
X2 = int(x2)
Y2 = int(y2)
Dr.swipe(X1, Y1, X2, Y2, t)
注:这里的 l = Size中的 “ l ” 是英文字母,不是数字 1
同理,验证码和交易密码无法通过定位元素去send_keys(),所以要切换回手机输入法打开软键盘然后对软键盘中的数字进行坐标定位,实现点击来输入验证码和交易密码,封装代码如下:
def tapYzm(self, Dr):
TouchAction(Dr).tap(x=125, y=848, count=1).wait(1000).perform() # 键位数字1
TouchAction(Dr).tap(x=359, y=848, count=1).wait(1000).perform() # 键位数字2
TouchAction(Dr).tap(x=595, y=848, count=1).wait(1000).perform() # 键位数字3
TouchAction(Dr).tap(x=126, y=971, count=1).wait(1000).perform() # 键位数字4
TouchAction(Dr).tap(x=685, y=748, count=1).wait(1000).perform() # 关闭软键盘
sleep(1)
def tapPasswd(self, Dr):
TouchAction(Dr).tap(x=35, y=835, count=1).wait(1000).perform() # 1
TouchAction(Dr).tap(x=107, y=835, count=1).wait(1000).perform() # 2
TouchAction(Dr).tap(x=181, y=835, count=1).wait(1000).perform() # 3
TouchAction(Dr).tap(x=253, y=835, count=1).wait(1000).perform() # 4
TouchAction(Dr).tap(x=324, y=835, count=1).wait(1000).perform() # 5
TouchAction(Dr).tap(x=396, y=835, count=1).wait(1000).perform() # 6
TouchAction(Dr).tap(x=685, y=748, count=1).wait(1000).perform() # 关闭软键盘
补充一个生成随机身份证号的方法(这个写的比较一般,不喜欢的可自行百度):
def createID(self):
province = "43,44" # 广东,湖南
cityH = "01,02,03,04,05,06,07,08,09,10,11,12,13,31"
cityG = "01,02,03,04,05,06,07,08,09,12,13,14,15,16,17,18,19,20,51,52,53"
area = "00"
year = []
for i in range(1949, 2001):
year.append(i)
year = str(year[random.randint(0, len(year) - 1)])
month = "01,02,03,04,05,06,07,08,09,10,11,12"
day = "01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31"
police = "83"
sexM = "1,3,5,7,9"
sexF = "0,2,4,6,8"
num = "0,1,2,3,4,5,6,7,8,9"
team = province.split(",")
p = team[random.randint(0, len(team) - 1)]
print("province = " + p)
if int(p) == 43:
team = cityH.split(",")
cH = team[random.randint(0, len(team) - 1)]
team = month.split(",")
m = team[random.randint(0, len(team) - 1)]
d = "0"
if m == "02":
team = day.split(",")
d = team[random.randint(0, len(team) - 4)]
if m in ("01", "03", "05", "07", "08", "10", "12"):
team = day.split(",")
d = team[random.randint(0, len(team) - 1)]
if m in ("02", "04", "06", "09", "11"):
team = day.split(",")
d = team[random.randint(0, len(team) - 2)]
team = sexM.split(",")
sM = team[random.randint(0, len(team) - 1)]
team = num.split(",")
n = team[random.randint(0, len(team) - 1)]
ID = p + cH + area + year + m + d + police + sM + n
print(ID)
return ID
else:
team = cityG.split(",")
cG = team[random.randint(0, len(team) - 1)]
team = month.split(",")
m = team[random.randint(0, len(team) - 1)]
print(m)
d = "0"
if m == "02":
team = day.split(",")
d = team[random.randint(0, len(team) - 4)]
if m in ("01", "03", "05", "07", "08", "10", "12"):
team = day.split(",")
d = team[random.randint(0, len(team) - 1)]
if m in ("02", "04", "06", "09", "11"):
team = day.split(",")
d = team[random.randint(0, len(team) - 2)]
team = sexF.split(",")
sF = team[random.randint(0, len(team) - 1)]
team = num.split(",")
n = team[random.randint(0, len(team) - 1)]
ID = p + cG + area + year + m + d + police + sF + n
print(ID)
return ID
4登陆测试环境分利宝app
def loginMsg(self, Dr):
commandP = 'adb shell ime set com.baidu.input_bbk.service/.PinyinIME' # 切换拼音输入法为当前输入法
commandA = 'adb shell ime set io.appium.android.ime/.UnicodeIME' # 切换appium输入法为当前输入法
os.system(commandA)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_username").clear() # 清空账号
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_username").send_keys("18148755362") # 输入账号
sleep(1)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_password").send_keys("123456") # 输入密码
sleep(1)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/btn_submit").click() # 登录
sleep(2)
def judge(self, element, Dr):
flag = True
try:
Dr.find_element_by_id(element)
return flag
except:
flag = False
return flag
def swipView(self, Dr, Size):
l = Size
TouchAction(Dr).press(x=360, y=480).wait(1000).move_to(x=0, y=405).wait(1000).move_to(x=200, y=0).wait(1000).release().wait(1000).perform()
这里介绍一个自写的判断弹窗的方法,这个方法在注册,充值,登陆,投标,提现都有经常用到。方便用于操作流程中分流操作的检验和判断,方法代码如下:如果检验到弹窗界面元素返回True,否则返回False
def judge(self, element, Dr):
flag = True
try:
Dr.find_element_by_id(element)
return flag
except:
flag = False
return flag
def swipView(self, Dr, Size)是关于手机滑动九宫格登陆app的操作,由于自动化测试过程滑动九宫格的操作比较繁琐,我暂时没有调用到操作逻辑中,而是选择跳过。当然这里还是附上滑动九宫格的代码(也是用TouchAction坐标定位):
def swip9(self, t, Dr, Size):
l = Size
TouchAction(driver).press(x=360, y=480).wait(1000).move_to(x=0, y=405).wait(1000).move_to(x=200,y=0).wait(1000).release().wait(1000).perform()
其中press就是手指按压屏幕的意思,wait是每个操作的等待时间间隔,move_to就是移动手指,release就是放开手指,perform是执行所有操作
注:这里注意三个坑:
(1)这里是以第一行中间宫格为起点,向下滑到第三行中间宫格,再向右滑动一个宫格。涉及坐标三个(x=360, y=480),(x=0, y=405),(x=200,y=0)这里不难看出后面两个坐标不太一样。这是因为第一个坐标是绝对坐标,即是uiautomatorviewer定位后直接拿到的坐标。但是到第二个坐标则是第一个坐标的相对坐标,所以x横坐标没有变化,第三个坐标是第二个坐标的相对坐标。那么第二和第三个坐标的绝对坐标是(360,885)和(560,885)所以相对坐标就是(360-360,885-480)和(560-360,885-885)
(2)release()也要加上wait(),意思是手指放开屏幕也要有一定的等待时间,不然要报错
(3)启动app或者说将要展示密码解锁界面前最好设置足够长的等待时间,否则容易获取不到界面而报错。
5测试环境分利宝账户充值
from time import sleep
from appium.webdriver.common.touch_action import TouchAction
import os
def chonZhi(self, Dr):
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_wealth_cg").click() # 进入我的
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_recharge").click() # 点击充值
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_money").send_keys("100000") # 充值金额
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/bt_ok").click() # 确认充值
# TouchAction(Dr).tap(x=355, y=510, count=1).wait(1000).perform()
sleep(6)
TouchAction(Dr).tap(x=355, y=808, count=1).wait(1000).perform() # 知道了
sleep(2)
commandP = 'adb shell ime set com.baidu.input_bbk.service/.PinyinIME' # 切换拼音输入法为当前输入法
commandA = 'adb shell ime set io.appium.android.ime/.UnicodeIME' # 切换appium输入法为当前输入法
TouchAction(Dr).tap(x=305, y=500, count=1).wait(1000).perform() # 点一下验证码输入框
os.system(commandP) # 执行切换输入法
sleep(2)
ChonZhi().tapYzm(Dr)
TouchAction(Dr).tap(x=350, y=588, count=1).wait(1000).perform() # 点一下交易密码输入框
sleep(2)
ChonZhi().tapPasswd(Dr)
TouchAction(Dr).tap(x=360, y=785, count=1).wait(1000).perform() # 同意协议并支付
sleep(8)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_my_account").click() # 回到我的账户
os.system(commandA) # 执行切换输入法
sleep(2)
与注册没有什么区别,可以定位元素的直接用元素ID操作,难以定位元素的则用坐标定位去操作
6测试环境分利宝账户投标
def touBid(self, Dr, name):
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_financing_cg").click() # 进入出借
sleep(2)
msg = ""
rows = Dr.find_element_by_id("android:id/list").find_elements_by_id("com.fenlibao.fenlibao:id/rl_itemView")
for i, j in enumerate(rows): # 遍历获取列表所有标
if i == 0:
txt = j.find_element_by_id("com.fenlibao.fenlibao:id/tv_bid_title").text
print(txt)
if txt == name:
msg = txt # 遍历获取标名正确的标,获取金额
money = msg.split("额")[1].split("元")[0].split(",")[0]
bidMoney = float(money + "000") # 获取标的金额
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_wealth_cg").click() # 进入我的
sleep(2)
realmoney = Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_balance").text
myMoney = realmoney
if "," in realmoney:
myMoney = float(realmoney.split(",")[0] + realmoney.split(",")[1]) # 获取账户可用金额
if myMoney < bidMoney: # 如果余额不足
ChonZhi.ChonZhi().chonZhi(Dr) # 充值
print("已充值1万元")
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_financing_cg").click() # 进入出借
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_financing_cg").click() # 进入出借
sleep(2)
rows = Dr.find_element_by_id("android:id/list").find_elements_by_id("com.fenlibao.fenlibao:id/rl_itemView")
for i, j in enumerate(rows):
if i == 0:
txt = j.find_element_by_id("com.fenlibao.fenlibao:id/tv_bid_title").text
print(txt)
if txt == name:
j.click() # 遍历获取标名正确的标,进入标
sleep(2)
break
TouchAction(Dr).tap(x=358, y=1234, count=1).wait(1000).perform() # 进入抢购
sleep(6)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_know").click() # 知道了
sleep(2)
emon = Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_residual_amount").text
enough = emon.split(",")[0] + "000"
print(enough)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/et_investMoney").send_keys(enough) # 填入金额
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/bt_buy").click() # 抢购
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/tv_my_invest").click() # 投标成功,进入我的项目
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_left").click() # 返回
sleep(2)
投标之前先加入遍历,检查出借界面是否有自己要投的那个标;过程中加入了一个余额逻辑,即获取标的金额去比对账户可用余额,当余额足够时直接投标,不足则现去充值
if "," in realmoney:
realhead = realmoney.split(",")[0]
myMoney = float(realhead + realmoney.split(",")[1])
print(myMoney) # 获取账户可用金额
if myMoney < bidMoney:
ChonZhi.ChonZhi().chonZhi(Dr) # 比较可用余额和标的金额
print("已充值1万元")
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_financing_cg").click() # 进入出借
sleep(2)
Dr.find_element_by_id("com.fenlibao.fenlibao:id/iv_financing_cg").click() # 进入出借
sleep(2)
总结
1Appium+python自动化测试效率性:
不得不说,实现真机自动化操作测试极大地提高了测试工作的效率。就如注册:总是需要输入11位正确格式手机号并且要到数据库查询获取验证码;开户:身份证是最大的硬伤,格式要求繁琐是其一,其二新网限制开户身份证不可重复使用,造成每次手动开户都要去网上查找身份证号。而自动化测试可以一键完成!
2Appium+python自动化测试实用性:
有关真机自动化测试是否方便的问题,个人觉得运行程序很简单,编写程序很蛋疼。很多时候一个可以感知的,可以确认为简单的问题也会有花费大半天的时间才能解决的情况。毕竟程序实现不同于手动操作,手动操作许多直接忽略的过程在程序中会变成“必填项”,当然这也同时扩大了测试场景的范围,抵消了手动操作的枯燥与繁琐,减轻了测试过程的心理压力,使测试工作更加具有质量和技术性。总体来说,真机自动化肯定是比手动测试要方便很多的,因为测试过程被浓缩在了“代码”,而不是鼠标和键盘上的点点刷刷!
3Appium+python自动化测试完整性:
真机自动化测试是否能涵盖所有测试的场景?这是许多人回去思考的问题,但事实上并不存在手动测试无法做到而自动化测试可以实现的情况。手动测试并不是所有可能场景罗列出来然后“笛卡尔积”或者说排列组合,势必要去重,去错;减少不必要的测试项,才能确保测试效率和质量。自动化测试也是一样,只是相比之下效率高出许多,对于已通过测试的功能场景可以一键验证,从而多出更多的时间和机会去测试新的需求。绝对的完整并没有必要,也不太可能!