# 移动应用测试

# 查看包名:

  • 方案一:如果你应用已经安装在手机上了,可以直接打开手机上该应用,进入到你要操作的界面,然后执行(注:一定要用cmd运行,powershell会报参数不正确):

    adb shell dumpsys activity recents | find "intent={"

    会出现如下信息:

    intent={act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher3/.Launcher}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=tv.danmaku.bili cmp=tv.danmaku.bili/.MainActivityV2}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.flysilkworm/.app.activity.FrameworkActivity}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.settings/.Settings}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10800000 cmp=io.appium.settings/.Settings}
    
    C:\WINDOWS\System32>adb shell dumpsys activity recents | find "intent={"
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=tv.danmaku.bili/.MainActivityV2}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher3/.Launcher}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.flysilkworm/.app.activity.FrameworkActivity}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.settings/.Settings}
        intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10800000 cmp=io.appium.settings/.Settings}

    其中 cmp=tv.danmaku.bili/.MainActivityV2就是/之前是包名(appPackage),之后是appActivity

  • 方案二:如果是已有apk在电脑上

    aapt dump badging D:\Desktop\软\iBiliPlayer-bili.apk | find "package"
    aapt dump badging D:\Desktop\软测\iBiliPlayer-bili.apk | find "launchable-activity"

    会出现如下信息:

    1、
    C:\WINDOWS\System32>aapt dump badging D:\Desktop\软\iBiliPlayer-bili.apk | find "package"
    package: name='tv.danmaku.bili' versionCode='6430500' versionName='6.43.0'
    2、 
    C:\WINDOWS\System32>aapt dump badging D:\Desktop\软\iBiliPlayer-bili.apk | find "launchable-activity"
    launchable-activity: name='tv.danmaku.bili.MainActivityV2'  label='' icon=''

    1、的name是包名,2、的name是appActivity(tv.danmaku.bili.MainActivityV2,

    可以省略tv.danmaku.bili)

  • 方案三:算是方案一的进阶吧(推荐)

    adb shell dumpsys window w |findstr \/ |findstr name=
    # 或者
    adb shell dumpsys activity activities | findstr mFocusedActivity

# 在UI Automator Viewer.bat中运行一次Python就连不上的问题:

特别提示:如果按照Python模板写,按q退出可以避免连不上的问题,相关代码如下

q = input('input q to quit')
if q == 'q':
    driver.quit()

方案一:重启模拟器

方案二:重启adb(推荐方案二,因为方案一很慢( ̄_ ̄|||))

adb kill-server & adb start-server

方案三:appium重连(原因:运行后appium占用指定端口与本身需要的端口冲突导致)

# Python中测试基本语法

参考语法文档:http://www.byhy.net/tut/auto/appium/02/

# 根据id
driver.find_elements_by_id("android:id/button2") #既可以找多个元素也可以找单个元素
# 点击事件
driver.find_element_by_id("cn.xuexi.android:id/comm_head_xuexi_score").click()
# tap点按(bounds 属性,停留的时间)
driver.tap([(850,1080)],300)
# 发送文字事件(resource-id)
sbox = driver.find_element_by_id('search_src_text')
sbox.send_keys('Doyoudo')
driver.press_keycode(AndroidKey.ENTER)
# 根据class元素
driver.find_elements_by_class_name('android.widget.TextView')
# 根据ACCESSIBILITY ID(content-desc属性)
driver.find_element_by_accessibility_id('找人')
# 根据Xpath
driver.find_element_by_xpath('//ele1/ele2[@attr="value"]')

# 模拟滑动
driver.swipe(start_x=x, start_y=y1, end_x=x, end_y=y2, duration=800)

# 按键
    # 输入回车键,确定搜索
    driver.press_keycode(AndroidKey.ENTER)
    # 返回
    driver.press_keycode(AndroidKey.BACK)
# 隐式等待 设置缺省等待10秒时间(不推荐)
driver.implicitly_wait(10)
# 强制等待 等5秒(推荐)
time.sleep(5)
# 显示等待 (有点多直接看链接吧)
https://blog.csdn.net/sinat_41774836/article/details/88965281
# 打开通知栏,返回直接BACK键
driver.open_notifications()
# 截屏手机,并且下载到指定目录中
import os
os.system('adb shell screencap /sdcard/screen3.png && adb pull /sdcard/screen3.png')

关于TouchAction类与MultiAction类的相关用法(九宫格解锁可以用touchaction)

联合查询:

# xpath方式: 可以联合@resource-id属性和@text文本属性来下定位
driver.find_element_by_xpath("//*[@resource-id='com.taobao.taobao:id/tv_scan_text'][@text='扫一扫']").click()

# 内嵌Java方式: 后面可以一直.name()这种方式添加(调用UI Automator API的java代码,实现最为直接的自动化控制。)
code = 'new UiSelector().text("追番").resourceId("tv.danmaku.bili:id/tab_title")'
ele = driver.find_element_by_android_uiautomator(code)
ele.click()
    # 具体java代码 来自谷歌Android文档:
    https://developer.android.google.cn/training/testing/ui-automator
    #常用列表
        text(String)         # 对应 text
        resourceId(String)   # 对应 resource-id
        description(String)  # 对应 content-desc
        className(String)    # 对应 class
        index(int)           # 对应 index
        instance(int)        # 是匹配的结果所有元素里面的第几个元素
        textContains(String) # 根据文本包含什么字符串(与text连用)

注:

ele = driver.find_element_by_android_uiautomator(
'new UiSelector(). className(" android.widget. TextView"). textContains("白月黑羽").instance(4)'
)
print(ele.text)
等同于下方代码
eles = driver.find_elements_by_android_uiautomator(
'new UiSelector(). className("android.widget. TextView"). textContains("白月黑羽")'
)
print(eles[4].text)

# Python基础模板(Python的第三方库appium-python-client)

from appium import webdriver
from appium.webdriver.extensions.android.nativekey import AndroidKey

desired_caps = {
    'platformName': 'Android', # 被测手机是安卓
    'platformVersion': '5', # 手机安卓版本
    'deviceName': 'HUAWEI', # 设备名,安卓手机可以随意填写
    'appPackage': 'tv.danmaku.bili', # 启动APP Package名称
    'appActivity': '.MainActivityV2', # 启动Activity名称
    'unicodeKeyboard': True, # 使用自带输入法,输入中文时填True
    'resetKeyboard': True, # 执行完程序恢复原来输入法
    'noReset': True,       # 不要重置App
    'newCommandTimeout': 6000,
    'automationName' : 'UiAutomator2'
    # 'app': r'd:\apk\bili.apk',
}

try:
    # 连接Appium Server,初始化自动化环境
    driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

    # 设置缺省等待时间
    driver.implicitly_wait(5)

    # 青少年保护
    iknow = driver.find_elements_by_id("text3")
    if iknow:
        iknow.click()

    driver.find_element_by_id("expand_search").click()
    sbox = driver.find_element_by_id('search_src_text')
    sbox.send_keys('Doyoudo')
    driver.press_keycode(AndroidKey.ENTER)

    eles = driver.find_elements_by_id("title")
    for ele in eles:
        print(ele.text)
    ele.click()

    q = input('input q to quit')
    if q == 'q':
        driver.quit()
except Exception as err:
    print('An exception happened: ' + str(err))
    q = input('error q to quit')
    if q == 'q':
        driver.quit()

# 自定义Python模板

import time

from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.extensions.android.nativekey import AndroidKey

desired_caps = {
    'platformName': 'Android',
    'platformVersion': '7',
    'deviceName': 'HUAWEI',
    'appPackage': 'tv.danmaku.bili',  # adb shell dumpsys activity activities | findstr mFocusedActivity
    'appActivity': '.MainActivityV2',  # 启动Activity名称
    'unicodeKeyboard': True,
    'resetKeyboard': True,
    'noReset': True,
    'newCommandTimeout': 6000,
    'automationName': 'UiAutomator2'
}

def id(a):
    return driver.find_element_by_id(a)

def ids(a):
    return driver.find_elements_by_id(a)

def xpath(a):
    return driver.find_element_by_xpath(a)

def xpaths(a):
    return driver.find_elements_by_xpath(a)

def desc(a):
    return driver.find_element_by_accessibility_id(a)

def class_names(a):
    return driver.find_elements_by_class_name(a)

def tap(a, b, c, d):
    return driver.tap([(a, b), (c, d)], 100)

def back():
    driver.press_keycode(AndroidKey().BACK)

def enter():
    driver.press_keycode(AndroidKey().ENTER)

def move(x, y, m, n):
    driver.swipe(start_x=x, start_y=y, end_x=m, end_y=n, duration=800)

def long_press(el1, el2):
    action = TouchAction(driver)
    action.long_press(el1).move_to(el2).release().perform()

try:
    driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

    driver.implicitly_wait(10)
    time.sleep(5)

    q = input('input q to quit\n')
    if q == 'q':
        driver.quit()
except Exception as err:
    print('An exception happened: ' + str(err))
    q = input('error q to quit')
    if q == 'q':
        driver.quit()

# appium测试ui界面模板(就是python中的desired_caps)注:这里内部必须都为双引号

{
    "platformName": "Android",
    "platformVersion": "57",
    "deviceName": "HUAWEI",
    "appPackage": "cn.xuexi.android",
    "appActivity": "com.alibaba.android.rimet.biz.SplashActivity",
    "unicodeKeyboard": true,
    "resetKeyboard": true,
    "noReset": true,
    "newCommandTimeout": 10000,
    "automationName": "UiAutomator2"
}

# adb基本命令

  • 先附上参考文档:

    https://www.wanandroid.com/blog/show/2310

  • 查看当前连接设备

    adb devices

  • 如果发现多个设备

    adb -s 设备号 其他指令

  • 查看顶部Activity

    • windows环境下:

      adb shell dumpsys activity | findstr "mFocusedActivity"

    • Linux、Mac环境下:

      adb shell dumpsys activity | grep "mFocusedActivity"

  • 查看日志

    adb logcat

  • 安装apk文件

    adb install xxx.apk

    推荐使用覆盖安装:

    adb install -r xxx.apk

  • 卸载App

    adb uninstall com.zhy.app

    如果想要保留数据,则

    adb uninstall -k com.zhy.app

  • 传递文件

    • 往手机SDCard传递文件

      adb push 文件名 手机端SDCard路径

    • 从手机端下载文件

      adb pull /sdcard/xxx.txt

  • 启动Activity

    adb shell am start 包名/完整Activity路径

  • 清除APP数据

    adb shell pm clear com.example.packagename

    注:该命令清除掉APP的缓存,还能把APP的数据给清空

  • 查看所有App的名称

    adb shell pm list packages

    注:该命令可以查看手机上的APP名称。可以在后面加上 -f ,这样还能显示该APP的路径,即:adb shell pm list packages -f 或者 adb shell pm path <PACKAGE>

    列出第三方应用adb shell pm list packages -3