这里我主要会介绍怎么自动的化操控模拟器和一些其它的测试.
1. 博主使用的是雷电模拟器,其它模拟器不适用此方法
雷电模拟器接口: http://www.ldmnq.com/bbs/thread-30-1-1.html
这里面是介绍了雷电模拟器调试接口的一些命令,需动手在cmd上先行操作!
2. 新建一个.py文件,开始编写脚本
这里主要实现了:
2.1 创建模拟器
2.2 修改模拟器的分辨率(调成手机)
2.3 启动模拟器
2.4 安装app和一些自动化调试的插件
# -*- coding:UTF-8 -*-
import os
import subprocess
from time import sleep
from optparse import OptionParser
class LeiDian(object):
def __init__(self):
# 启动虚拟机
self.start_vm = 'dnconsole.exe launch --name %d'
# 新增虚拟机
self.add_vm = 'dnconsole.exe add --name %d'
# 修改分辨率
self.alter_ratio = 'dnconsole.exe modify --index %d --resolution 540,960,240'
# 安装app
self.install_app = 'dnconsole.exe installapp --index %d --filename %s'
# app路径
self.app_path = 'D:\\Changzhi\Facebook_x86_128.apk'
# dnconsole.exe路径
self.ld_path = 'D:\\Changzhi\dnplayer2'
# 查看虚拟机所有信息
self.all_vm_info = 'doconsole.exe list2'
# 切换目录
def chair(self):
try:
retval = os.getcwd()
print("当前工作目录为 %s" % retval)
# 切换到当前路径
os.chdir(self.ld_path)
# 查看修改后的工作目录
retval2 = os.getcwd()
print("当前工作目录已修改为 %s" % retval2)
except Exception as e:
print(e)
else:
self.view_vm(index=61)
# 查看虚拟机
def view_vm(self, index):
data = subprocess.Popen('dnconsole.exe list2', stdout=subprocess.PIPE, universal_newlines=True)
# 虚拟机全部信息
# data_info = data.stdout.read()
number_list = []
for line in data.stdout:
# 含有换行符
info = line.strip().split(',')
vm_number = info[1]
number_list.append(vm_number)
if str(index) in number_list:
print('该虚拟机已经存在')
else:
self.make_vm(index=index)
# 创建模拟器
def make_vm(self, index):
subprocess.call(self.add_vm % index)
print('创建模拟器{}成功!'.format(index))
subprocess.call(self.alter_ratio % index)
print('修改模拟器{}分辨率成功!'.format(index))
subprocess.call(self.start_vm % index)
print('启动模拟器{}'.format(index))
print('开始安装Facebook!')
code = subprocess.call(self.install_app % (index, self.app_path))
if code == 0:
sleep(60)
print('安装Facebook成功!')
print('开始安装uiautomator2!')
subprocess.call('python -m uiautomator2 init')
print('安装uiautomator2成功!')
if __name__ == '__main__':
leidain = LeiDian()
leidain.chair()
上面代码主要的流程是:
切换当前的工作目录 ------> 调用雷电模拟器命令代码
里面有些参数不懂得话,自行输出查看即可了解
3. 启动app,输入账号与密码,登录app
import uiautomator2 as u2
from time import sleep
import uiautomator2.ext.htmlreport as htmlreport
class LeiDian(object):
def __init__(self):
try:
self.d = u2.connect_usb('emulator-5656')
except Exception as e:
print(e)
# 全局设置,每个ui点击之后休眠1.5s
self.d.click_post_delay = 1.5
hrp = htmlreport.HTMLReport(self.d)
hrp.patch_click()
# 连接测试
def link_test(self):
if self.d.info['naturalOrientation'] == True:
print('设备连接正常!')
self.run_app()
else:
print('设备连接出现问题!请检查后重试!')
# 运行app
def run_app(self):
# 先返回主菜单界面
self.d.press('home')
self.d(text="Facebook").click()
self.login_app()
# 登录app
def login_app(self):
self.d(resourceId="com.facebook.katana:id/login_username").set_text('账号')
self.d(resourceId="com.facebook.katana:id/login_password").set_text('密码')
try:
self.d(text='登录').click()
except Exception as e:
print(e)
else:
print('正在登录>>>>>>\n请稍后>>>>>>')
if __name__ == '__main__':
leidain = LeiDian()
leidain.link_test()
4. 查找设备数量(也是非常有用的)
# 查找设备数量
def finddevices():
data = subprocess.Popen('adb devices', stdout=subprocess.PIPE, universal_newlines=True)
data_info = data.stdout.read()
devices = re.findall(r'(.*?)\s+device', data_info)
if len(devices) > 1:
deviceIds = devices[1:]
print('共找到%s个手机' % str(len(devices)-1))
for i in deviceIds:
print('ID为%s' % i)
return deviceIds
else:
print('没有找到手机,请检查')
return
finddevices()
5. 当你想要找的元素有多个相同的实例, 或者有时屏幕可能包含多个具有相同属性的视图时, 可以使用以下这种写法
year_number=int(d(className="android.widget.LinearLayout").child(className="android.widget.NumberPicker", instance=2).child(className="android.widget.EditText").get_text())
其中child这个用法我就不多说了, 说一下instance这个参数, 它的主要的作用就是在有相同属性的时候定位到你想要的第几个属性默认是从0开始, 也就是你将instance设为0之后, 代码选择的是属性的第一个实例(以此类推)......
例如:
6. 元素点的状态辨别, 有些时候你定的元素的位置其实是没有问题的, 但是它总是或多或少的去点击另外一个看似毫不相干的点, 这个时候我们就要让它在重新点击回我们想要的位置, 也许你会想到做判断, 这是没有问题的, 如果它点击其它点较多的情况下适合. 但如果它点击其它的点就几乎一个的时候, 我们可以使用, 用这个点的点击状态来进行判断.
if d(descriptionStartsWith="Selected, Friend Requests").exists:
time.sleep(2)
d(resourceId="com.facebook.katana:id/news_feed_tab").click_exists(timeout=15)
上面这段代码的意思就是说, 当if里面的这个点的点击状态存在或者已触发, 那么让它在重新点击我们之前想要的位置.
7. 如果你不太会将可以滚动的元素滚动到指定位置时你可以试试这个方法(在git上还有它类似的写法)
d(scrollable=True).scroll.to(text=u"Share")
上面这句代码的意思就是说滚动到元素文本为Share上, 是不是很方便~~~~~~
陆陆续续会补充一些有用的代码或者逻辑
项目已上传https://github.com/zhixideyu/uiautomator2---FaceBook