appium自动化测试框架,具体信息不便我重复,网上能够查找的资料也很多
我项目中在做自动化测试的过程中,遇到密码键盘,需要进行模拟点击输入的问题,使用appium提供的sent_keys方法不管用,原因是密码键盘必须得点击密码键盘进行输入才能够通过。
密码键盘的原理是每次点击一个按键,进行一次加密,点击结束后,按登录才能够登录通过。而send_keys的输入方法是直接使用系统的键盘发送键值到输入框,没有经过点击操作。
密码键盘的一个难点就在于,它没有id,而appium提供的定位方法大都是通过ID,name,class等元素进行页面定位的,看过所有的定位方法后,发现了通过坐标值也可以进行定位,而密码键盘要想定位成功,必须通过图像识别,识别出键盘所在的位置坐标信息
下面的功能就是通过图像识别方法对密码键盘所在的坐标进行识别。
所遇到的密码键盘如下图所示
面还有输入框的内容,我进行了截取。
解决思路:
1、图像识别,然后点击坐标
2、开发配合,给特定的app包,解除安全键盘。
而对于非自己的app是无法使用第二种方法的。
图像识别找到了opencv里面有match Template方法,可以在图片中找指定的图片,
步骤:
1、首先需要操作的位置进行截图并保存起来,切记按原图大小截取,尽可能小,比如:
2、然后就是在截取的屏幕上面查找这些数字对应的位置
3、按照位置在屏幕上点击
实现代码:
以需要输入密码为例,我写了如下代码,需要传入截图图片路径,还需要输入的密码。前面我已经将各个数字的图片保存在了本地,并以n0.jpg,n1.jpg,…保存,并和脚本放在一起。
我使用python写的脚本,当然你还需要安装opencv,下载路径:http://opencv.org/releases.html下载后吧build下面的python里面的cv2.pyd文件目录下面的lib\site-packages里面
代码如下
#coding:utf-8
import os
import time
import cv2
import numpy as np
import matplotlib.pyplot as plt
def get_pay_keyboard_number_location(im, pwd):
numbers = set(list(pwd))
templates = {}
positions = {}
nimgpath = "" #数字图片不在同目录时使用
for i in numbers:
templates[i] = os.path.join(nimgpath, "n{}.jpg".format(i))
start = time.time()
img_rgb = cv2.imread(im)
for teNum, tepath in templates.items():
# print(tepath)
template = cv2.imread(tepath)
h, w = template.shape[:-1]
res = cv2.matchTemplate(img_rgb, template, cv2.TM_CCOEFF_NORMED)
threshold = .95 # 匹配度参数,1为完全匹配
loc = np.where(res >= threshold)
if len(loc) > 0:
positions[teNum] = zip(*loc[::-1])[0]
else:
print("Can not found number: [{}] in image: [{}].".format(tepath, im))
end = time.time()
print(end-start)
return [positions[n] for n in pwd]
if __name__ == "__main__":
ls = get_pay_keyboard_number_location('keyboard.jpg', '1234567890')
print(ls)
上面的代码实现了获取每个数字的坐标,并以列表进行返回。
拿到坐标后就可以直接的通过appium的tap,如
TouchAction(driver).long_press(x = 180,y = 1400).perform()
进行点击操作了。
代码不一定严谨,欢迎指正