Appium、adb控制Android手机和实战项目

Appium、adb控制Android手机和实战项目

  • adb常用命令
  • Appium中API
  • 元素定位操作API
  • 滑动和拖拽事件(appium<2.0版本)
  • 高级手势TouchAction
  • 手机操作API
  • adb实例---获取手机详细信息
  • Appium实战---连接参数解析

Appium和adb环境搭建请大家参考其它文章,我这里就不在过多描述了。如果安装和使用过程中出现了问题,欢迎大家留言讨论

adb常用命令

  1. 获取当前启动app的包名和启动名
adb shell dumpsys window | findstr mFocusedApp

# 执行的结果
mFocusedApp=AppWindowToken{8a898b1 token=Token{7f8cfad ActivityRecord{8522505 u0 com.tencent.mm/.plugin.webview.ui.tools.WebViewUI t22269}}}
mFocusedApp=Token{7f8cfad ActivityRecord{8522505 u0 com.tencent.mm/.plugin.webview.ui.tools.WebViewUI t22269}}
包名:com.tencent.mm,启动(界面):.plugin.webview.ui.tools.WebViewUI
  1. 获取app启动时间
adb shell am start -W 包名/启动名
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.taobao.taobao/com.taobao.tao.TBMainActivity }
Status: ok
LaunchState: COLD
Activity: com.taobao.taobao/com.taobao.tao.TBMainActivity
TotalTime: 1057
WaitTime: 1060
Complete

# 结果解析
ThisTime:该界面(activity)启动耗时(毫秒)
TotalTime:应用自生启动耗时=ThisTime+应用application等待资源启动时间(毫秒)
WaitTime:系统启动应用耗时=TotalTime+系统资源启动时间(毫秒)
  1. 获取包名和启动名
    1. aapt dump badging + apk绝对路径 |findstr package (只能获取包名)
    2. adb shell dumpsys window | findstr mFocusedApp (需要打开app后再执行这行命令)

Appium中API

  1. 输出当前程序的包名
    driver.current_package
  2. 输出当前程序的界面名
    driver.current_activity
  3. 检测应用是否存在
    driver.is_app_installed("包名")
  4. 安装软件
    driver.install_app('apk的绝对路径')
  5. 卸载软件
    driver.remove_app("包名")
  6. 应用回到后台,然后再返回到前台
    driver.background_app(2)
  7. 关闭当前操作的app。不会关闭驱动对象
    driver.close_app()
  8. 关闭驱动对象,同时关闭所有关联的app
    driver.quit()
  9. 使用uiautomatorviewer注意点
    1. 命令行窗口不要关闭
    2. 如果uiautomatorviewer闪退
      • 更换jdk为1.8
    3. 点击第二个按钮的时候报错
      • 重启adb
        • adb kill-server
        • adb start-server

元素定位操作API

元素的定位基于当前屏幕范围内展示的可见元素

  1. 定位一个元素
    只有获取元素之后,才能对元素进行操作

    1. 通过id定位元素
      id_value:元素的resource-id属性值
      driver.find_element(AppiumBy.ID, resource-id)
    2. 通过class_name定位一个元素
      class_value:元素的class属性值
      driver.find_element(AppiumBy.CLASS,class_value)
    3. 通过xpath定位一个元素
      xpath_value:定位元素的xpath表达式
      driver.find_element(AppiumBy.XPATH,xpath_value)
    4. 通过accessibility id定位元素
      accessibility id:定位元素的accessibility id
      driver.find_element(AppiumBy.ACCESSIBILITY_ID, accessibility id)
  2. 定位多个元素
    加一个s就可以了,获得的是一个列表
    driver.find_elements(AppiumBy.CLASS,class_value)

  3. 点击事件
    element.click()

  4. 输入和清空输入框内容
    element.send_keys(value)
    清空文本
    element.clear()

  5. 获取文本内容
    element.text

  6. 获取元素的位置和大小

    1. 获取元素位置(返回字典,x为元素的x坐标,y为元素的y坐标)
      element.location
    2. 获取元素大小(返回字典,width为宽度,height为高度
      element.size
  7. 获取元素的属性值(返回值:根据属性名得到的属性值)

    element.get_attribute(value)  # value:元素的属性
    value='name' 返回content-desc/text属性值
    value='className'返回class属性值,只有API>=18才支持
    value='resourceId'返回resource-id属性值,只有API>=18才支持
    

滑动和拖拽事件(appium<2.0版本)

  1. swipe滑动事件
    从一个坐标位置滑动到另外一个坐标位置,只能是两个点之间的滑动
    driver.swipe(start_x: int, start_y: int, end_x: int, end_y: int,duration)
    duration:持续时间,执行这个滑动操作一共需要多长时间
    特点:
    • 参数是坐标点
    • 持续时间短,惯性大;持续时间长,惯性小。
  2. scroll滑动事件
    从一个元素滑动到另外一个元素,直到页面自动停止(惯性非常大)
    driver.scroll(origin_el: WebElement, destination_el: WebElement)
  3. drag_and_drop拖拽事件
    从一个元素滑动到另外一个元素,第二个元素替代第一个元素原本屏幕上面的位置
    driver.drag_and_drop(origin_el: WebElement, destination_el: WebElement)

    滑动和拖拽无非就是考虑是否有”惯性“,以及传入的参数是”元素“还是”坐标“

高级手势TouchAction

TouchAction可以实现一些针对手势的操作,比如滑动、长按、拖拽等。可以将这些基本手势组合成一个相对复杂的手势。

使用步骤:

  • 创建TouchAction对象
  • 通过对象调用执行的手势
  • 通过perform()函数执行动作
  1. 手指轻敲操作
    模拟手指对某个元素或坐标按下并快速抬起
    TouchAction(driver).tap(element=None,x=None,y=None).perform()

  2. 按下和抬起操作

    1. press按下(一直按)
      TouchAction(driver).press(element=None,x=None,y=None).perform()
    2. release抬起
  3. 等待操作
    TouchAction(driver).wait(ms=0).perform()

  4. 长按操作

    模拟手指对元素或坐标的长按操作。比如,长按某个按钮弹出菜单。

    TouchAction(driver).long_press(el=None,x=None,y=None,duration=1000).perform()
    duration:长按时间(毫秒)

  5. 移动操作
    模拟手指移动,比如,手势解锁需要先按下,再移动
    TouchAction(driver).move_to(el=None,x=None,y=None).perform()

手机操作API

  1. 获取手机分辨率
    自动化测试中可能会根据当前设置的屏幕分辨率来计算一些点击或滑动的坐标
    driver.get_window_size()(返回的是一个字典)

  2. 获取手机的截图
    filename:图片的路径,电脑保存路径
    driver.get_screenshot_as_file(filename)

  3. 获取和设置手机网络

    • 获取当前手机网络
      driver.network_connection (返回的是一个数字)
    • 设置当前网络
      driver.set_network_connection(int)
  4. 发送键到设备

    模拟按’返回键‘,’home‘键等操作

    driver.press_keycode(keycode,metastate=None)

    keycode:https://www.cnblogs.com/larack/p/4223465.html
    metastate:关于被发送的关键代码的原信息,一般为默认值

  5. 操作手机的通知栏
    打开手机通知栏
    driver.open_notifications()
    关闭通知栏
    滑动或按返回键

adb实例—获取手机详细信息


import os
import sys
import time

def a():
    print('该手机基本信息如下所示:')

    print("设备型号:",end='')
    sys.stdout.flush()
    os.system('adb shell getprop ro.product.model')

    print('Android系统版本:', end='')
    sys.stdout.flush()
    os.system('adb shell getprop ro.build.version.release')

    print('设备的序列号(设备号):', end='')
    sys.stdout.flush()
    os.system('adb get-serialno')

    print('设备屏幕分辨率:', end='')
    sys.stdout.flush()
    os.system('adb shell wm size')

    print('屏幕密度:', end='')
    sys.stdout.flush()
    os.system('adb shell wm density')

    print('android id:', end='')
    sys.stdout.flush()
    os.system('adb shell settings get secure android_id')

    print('本机IP地址:', end='')
    sys.stdout.flush()
    os.system('adb shell netcfg|findstr wlan0')

    print('SDK 版本:', end='')
    sys.stdout.flush()
    os.system('adb shell getprop ro.build.version.sdk')

    print('手机品牌:', end='')
    sys.stdout.flush()
    os.system('adb shell getprop ro.product.brand')

    print('Android 安全补丁程序级别:', end='')
    sys.stdout.flush()
    os.system('adb shell getprop ro.build.version.security_patch')

    print('处理器型号:', end='')
    sys.stdout.flush()
    os.system('adb shell getprop ro.product.board')

    print('CPU 支持的 abi 列表:', end='')
    sys.stdout.flush()
    os.system('adb shell getprop ro.product.cpu.abilist ')

a()
while True:
    pass

在print函数后面执行os的时候,需要在中间加入sys.stdout.flush(),因为输出被缓冲,您必须刷新此缓冲区。不然后果就是所有os全部执行完毕后,再执行print语句

打包后程序运行输出结果(我的手机是华为p30pro)

Appium、adb控制Android手机和实战项目_第1张图片

代码写完后,我们可以使用pyinstaller打包成为一个可执行的exe程序

1. 首先在cmd中下载pyinstaller。pip install pyinstaller
2. 在当前程序的目录下打开cmd
3.输入以下命令,在dist目录下就会生成一个可执行的exe。文件
pyinstall -F 程序名称.py

Appium实战—连接参数解析

from appium import webdriver
import time

# 连接手机参数

desired_caps = {
    # 获取设备信息
    'platformName': 'Android',
    # 固定写法Appium
    'automationName': 'Appium',
    # adb devices
    'deviceName': 'MQS0219909002236',
    # 获取系统版本号
    # adb shell getprop ro.build.version.release
    'platformVersion': '10',
    # 获取应用程序的识别号
    # 通过下面的命令可以直接得到启动 app 的 appPackage 参数和 appActivity 参数,
    # adb shell dumpsys window | findstr mCurrentFocus
    # adb shell dumpsys window |findstr mFocusedApp 最好使用这个
    # 前面是包名,后面是启动名activity

    # aapt dump badging D:\test\xxx.apk(APK的全名)
    "appPackage": "tv.danmaku.bili",
    "appActivity": ".MainActivityV2",
    # 默认选择接受弹窗的条款,有些app启动的时候,会有一些权限的弹窗
    'autoAcceptAlerts': 'true ',
    "noReset": "true",
    "dontStopAppOnReset": "true"
}

# 发送命令连接手机,返回driver信息
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=desired_caps)
# 设置等待时间,如果不给时间的话可能会找不到元素
driver.implicitly_wait(5)
# 输出当前程序的包名
print(driver.current_package)
# 输出当前程序的界面名
print(driver.current_activity)

你可能感兴趣的:(python,adb,python)