自动化管理平台操作手册:
APP元素定位法(实时):
1.下载元素定位安装包:pip install -U uiautomator2
pip install -U uiautomator2 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
2.下载图形化界面安装包:pip install -U weditor
pip install -U weditor -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
3.打开界面获取坐标:weditor
4.在手机上进行初始化安装APP:python -m uiautomator2 init
备注:安装文件路径:电脑:D:\Users\50000206.uiautomator2\cache
手机:/data/local/tmp/
安装不成功解决办法:1.将手机USB调试关闭后打开
2.adb shell pm install -t /data/local/tmp/*.apk
weditor连接异常:换个手机?
设备列表不显示设备:换个手机?
pip安装异常:缺少Visual C ++ 14.0工具?
外链: https://www.lanzous.com/b0cju0voh
密码: htjy
ATXServer设备控制:
环境搭建及操作步骤:
0.uiautomator2使用教程:https://github.com/openatx/uiautomator2
1.安装node.js【和手机建立socket】、下载rethinkdb工具【容器类似Tomcat】、下载atxserver2-master源码【平台显示】、下载atxserver2-android-provider-master源码【获取设备信息】
2.入口:https://github.com/openatx/atxserver2
3.下载rethinkdb工具地址:https://rethinkdb.com/docs/install/
4.启动rethinkdb工具命令:rethinkdb.exe --http-port 8090
5.atxserver2服务器部署【pip install atxserver2】
6.启动并设置监听端口命令:python main.py --port 5000
7.Android设备接入地址:https://github.com/openatx/atxserver2-android-provider
8.启动命令:python main.py --server localhost:5000
9.设备管理共享地址:http://10.118.3.104:5000/devices
10.查看手机的坐标:weditor工具
11.shell脚本:shell测试脚本【monkey测试】
11.monkey整体测试命令【平台默认adb shell 】:monkey -v -v -v -s 2 --throttle 100 --pct-touch 60 --pct-motion 0 --pct-trackball 0 --pct-nav 0 --pct-majornav 0 --pct-syskeys 0 --pct-appswitch 0 --pct-anyevent 0 -p com.ss.android.ugc.aweme --ignore-crashes --ignore-timeouts --ignore-security-exceptions 10000 1>/mnt/sdcard/monkey.log 2>/mnt/sdcard/monkeyError.log
11.monkey指定APP测试命令: monkey -p com.coloros.calculator -v 5000
12.操作手机命令:input keyevent 26 # power键
input keyeven 3 # home键
input keyeven 82 # menu键
input keyeven 4 # back键
input keyeven 19 # 向上【input swipe 540 1300 540 500 1000】
input keyeven 20 # 向下
input keyeven 21 # 向左
input keyeven 22 # 向右
input keyeven 83 # 解锁
13.monkey测试错误关键单词
14.python脚本测试:python脚本UI测试
15.利用weditor工具抓取定位控件
16.集成uiautomator2+pytest+allure编写测试脚本,输出测试报告
17.将脚本集成到jenkins平台做定时任务,及定时输出测试报告。
18.持续优化
appium_app.py
# coding:utf-8
import os
from appium import webdriver
import time
class Event:
'''常用keyevent事件'''
KEYCODE_HOME = 3 # home键
KEYCODE_MENU = 82 # menu键
KEYCODE_BACK = 4 # back键
KEYCODE_POWER = 26 # power键
KEYCODE_DPAD_UP = 19 # 向上
KEYCODE_DPAD_DOWN = 20 # 向下
KEYCODE_DPAD_LEFT = 21 # 向左
KEYCODE_DPAD_RIGHT = 22 # 向右
KEYCODE_NOTIFICATION = 83 # 解锁
# 点击返回键
def back(keyname=Event.KEYCODE_BACK):
' 执行adb keyevent事件 参数从Event类里面关联'
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
# 点击home键
def home(keyname=Event.KEYCODE_HOME):
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
# 点击菜单键
def menu(keyname=Event.KEYCODE_MENU):
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
# 向上滑动
def up(keyname=Event.KEYCODE_DPAD_UP):
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
# 向下滑动
def down(keyname=Event.KEYCODE_DPAD_DOWN):
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
# 向左滑动
def left(keyname=Event.KEYCODE_DPAD_LEFT):
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
# 向右滑动
def right(keyname=Event.KEYCODE_DPAD_RIGHT):
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
# adb也可以输入文本
def input_text(text):
u'adb输入是text文本,不支持中文'
adb = 'adb shell input text %s' % text
os.system(adb)
# 按一下电源键,唤醒屏幕
def power(keyname=Event.KEYCODE_POWER):
adb = 'adb shell input keyevent %s' % keyname
os.system(adb)
def driver_init():
devices = {}
# cmd窗口输入:adb devices
devices["deviceName"] = "eaf7812f"
# cmd窗口输入:Android、iOS
devices["platformName"] = "Android"
# cmd窗口输入:adb shell getprop ro.build.version.release
devices["platformVersion"] = "9"
# cmd窗口输入:adb shell "dumpsys window | grep mCurrentFocus" 手动打开目标apk,重复输入上述命令!
# 查看apk路径:adb shell pm path 包名
devices["appPackage"] = "com.coloros.calculator"
devices["appActivity"] = "com.android.calculator2.Calculator"
devices["noReset"] = True
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", devices) # 连接Appium
driver.find_element_by_id("com.coloros.calculator:id/clr").click()
driver.find_element_by_id("com.coloros.calculator:id/digit_7").click()
driver.find_element_by_accessibility_id("加").click()
driver.find_element_by_id("com.coloros.calculator:id/digit_3").click()
driver.find_element_by_accessibility_id("等于").click()
time.sleep(3)
# driver.quit()
if __name__ == '__main__':
# power()
for i in range(1, 11):
driver_init()
atxserver_init.py
import atxserver2
client = atxserver2.Client("http://10.118.3.104:5000", "c0fc9737598a47a9b6152a0c465cfb24")
print(client.user_info())
for device in client.list_device():
print("Device", device)
device.acquire() # 占用设备
device.acquire(email="tz@anonymous.com", idle_timeout=5000) # 指定用户占用设备, 时长6000秒
# device.release() # 释放设备
print(device.remote_connect_address)
print(device.info)
print(device.atx_agent_address) # 获取设备信息
Serial_Devices_View.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import re
import sys
import threading
import time
from concurrent.futures import ProcessPoolExecutor
from tkinter.messagebox import showinfo
import uiautomator2 as u2
import adbutils
import windnd
from adbutils import adb
import atxserver2
import tkinter as tk
def client():
list_client = []
atx_servers = []
client = atxserver2.Client("http://10.118.3.104:5000", "c0fc9737598a47a9b6152a0c465cfb24")
for device in client.list_device():
device.acquire() # 占用设备
device.acquire(email="tz@anonymous.com", idle_timeout=60000) # 指定用户占用设备, 时长6000秒
clientdevices = device.remote_connect_address
atx_server = device.atx_agent_address
list_client.append(clientdevices)
atx_servers.append(atx_server)
return list_client, atx_servers
def adb_connect():
connect_list = []
devices_list, b = client()
for i in devices_list:
adb.connect(i)
time.sleep(2)
for i in adb.devices():
if re.findall(':', i.serial):
connect_list.append(i.serial)
return connect_list, b
def Arrange_view(adblist, x):
# window_x='1920'
iphone_x = '200'
if int(x) > 1500:
x = 50
y = 560
os.system(
'scrcpy -s ' + adblist + ' --window-x ' + str(x) + ' --window-y ' + str(y) + ' --window-width ' + iphone_x)
else:
y = 50
os.system(
'scrcpy -s ' + adblist + ' --window-x ' + str(x) + ' --window-y ' + str(y) + ' --window-width ' + iphone_x)
list_files = []
def wintk(adblist, atxserver):
'''
创建可视化控制窗口
:return:
'''
window = tk.Tk()
window.title('设备控制')
window.geometry('%dx%d+%d+%d' % (360, 800, 1600, 200))
'''
创建文件拖拽区
'''
button_listName = [['亮屏解锁', '息屏'], ['Home', 'Back'], ['XXX', 'XXX'], ['XXX', 'XXX'], ['XXX', 'XXX'], ['XXX', 'XXX']]
var2 = tk.StringVar()
var2.set('拖拽放入') # 为变量var2设置值
# 创建Listbox
lb = tk.Listbox(window, width=20, height=2, listvariable=var2)
lb.grid(row=0, column=2, padx=10, pady=10, ipadx=20, ipady=20)
bs = tk.Button(window, text='安装/Push', command=lambda: push(adblist))
bs.grid(row=0, column=3, padx=0, pady=0, ipadx=0, ipady=0)
# command =
bs1 = tk.Button(window, text='屏幕同步', command=screnn_sy)
bs1.grid(row=1, column=3, padx=0, pady=0, ipadx=0, ipady=0)
def drag_file(files):
lb.delete(0)
for n, i in enumerate(files):
lb.insert(n, i.decode('gbk'))
list_files.append(i.decode('gbk'))
windnd.hook_dropfiles(window, func=drag_file)
'''
遍历创建按钮
'''
global z
global btn
for n, i in enumerate(button_listName):
for j, z in enumerate(i):
b1 = tk.Button(window, text=str(z), width=10, height=5, command=lambda i=z: click_event(i, atxserver))
b1.grid(row=n + 2, column=j + 2, padx=0, pady=0, ipadx=20, ipady=20)
window.mainloop()
def click_event(i, atxserver):
'''
响应点击事件
:return:
'''
def test(id, atxservers):
d = u2.connect(atxservers)
if id == '亮屏解锁':
d.unlock()
elif id == '息屏':
d.screen_off()
elif id == 'Home':
d.press("home")
elif id == 'Back':
d.press("back")
for b in atxserver:
threading.Thread(target=test, args=(i, b)).start()
def push(adblist):
'''
PUSH文件/安装apk到手机
:param atxseverse:
:return:
'''
print(adblist)
def t(b):
u = u2.connect(b)
for i in list_files:
if re.findall('.apk', i):
print('adb -s ' + b + ' install -r ' + i)
os.popen('adb -s ' + b + ' install -r ' + i)
else:
u.push(i, '/sdcard/')
for b in adblist:
threading.Thread(target=t, args=[b]).start()
adblist, atx_server = adb_connect()
def screnn_sy():
print(adblist)
x = 50
for n, i in enumerate(adblist):
if n == 0:
pass
else:
x = x + 220
t1 = threading.Thread(target=Arrange_view, args=(i, str(x)))
t1.start()
def init(atx_server):
for i in atx_server:
d = u2.connect(i)
# d.screen_on()
d.unlock()
t2 = threading.Thread(target=wintk, args=(adblist, atx_server))
t2.start()
t3 = threading.Thread(target=init, args=[atx_server])
t3.start()