有测试问题请微信联系作者,备注来意(点击此处添加)
240
一名普通的测试打工人;专注自动化测试技术研究、实践、总结、分享、交流。
用我8年+的经历,给大家带来更多实用的干货。
人若有志,就不会在半坡停止。

【APP自动化基础】appium与设备交互方法

获取设备信息

获取设备大小

window_size = driver.get_window_size()
print(window_size)      # {'width': 1080, 'height': 1920}

获取当前应用的信息

driver.current_activity      # 获取当前应用的activity信息:.MainSettings
driver.current_package       # 获取当前应用的package信息:com.android.settings

获取设备上下文信息(切换H5操作)

上下文:在程序中context我们可以理解为当前对象在程序中所处的一个环境。 比如前面提到的App一个界面是属于Activity类型,也就是Android界面环境,但是当访问内嵌的网页是属于另外一个环境(网页环境),两者处于不同的一个环境。

driver.contexts           # 获取所有的上下文信息,返回值为列表类型
driver.context            # 获取当前上下文,返回值为字符串类型
driver.current_context    # 获取当前上下文,返回值为字符串类型

打印输出当前context,如果一直显示为Natvie App,则webview未开启

案例

import time
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy

desired_caps = {
    "platformName": "Android",
    "platformVersion": "7.1.2",
    "udid": "127.0.0.1:62001",
    "appPackage": "com.xkw.client",
    "appActivity": "com.zxxk.page.main.LauncherActivity",
    "noReset": True,
    'automationName': 'uiautomator2',
    "chromeOptions": {'w3c': False},
    "chromedriverExecutable": r"C:\Users\Administrator\Desktop\chromedriver_win32\chromedriver.exe"
}

driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)
driver.implicitly_wait(30)

# 点击活动入口
driver.find_element(AppiumBy.ID, "com.xkw.client:id/iv_horizontal_pic").click()
time.sleep(5)
# 获取contexts
context = driver.contexts
# 切换到webview
driver.switch_to.context(context[-1])

driver.find_element(AppiumBy.ID, "getgifts").click()
time.sleep(1)
# 切换到Native
driver.switch_to.context("NATIVE_APP")
driver.find_element(AppiumBy.ID, "com.xkw.client:id/common_toolbar_back_img").click()

APP中H5调试

  1. 打开USB调试,连接PC
  2. 手机或模拟器进入H5页面
  3. Edge浏览器输入:edge://inspect/#devices
    若使用chrome,则需要代理,否则inspect报404:chrome://inspect/#devices

驱动配置及下载

desired_capabilities需要配置driver目录

'chromedriverExecutableDir': 'browser_driver',    # 浏览器版本对应的driver驱动版本存放目录

查看当前手机浏览器版本

Edge浏览器输入:edge://inspect/#devices

对应手机浏览器版本的driver下载

chromedriver下载地址

设备操作

等待activity出现操作

driver.wait_activity(activity, timeout, interval=1)
等待目标页面出现,若在设置时间内目标页面出现则直接跳出等待,同时返回True; 若超过设置时间目标页面仍未出现则返回False

  • activity:目标activity
  • timeout:超时时间设置,单位为s
  • interval:循环查询的时间间隔,单位为s,默认为1s

应用场景

主要用于一些应用启动时界面的activity与进入应用时界面的activity不一致,这样就会存在等待时间,而这个等待时间每次可能不一样,故可通过设置超时来等待。

案例

driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)
is_target_activity = driver.wait_activity("com.kugou.common.useraccount.app.KgUserLoginAndRegActivity", 10)
if is_target_activity is True:
    print("成功进入目标主页面,可继续执行其他操作")
else:
    print("超过未进入目标主页面")

关闭APP和退出设备

driver.close_app()       # 关闭当前app
driver.quit()            # 关闭驱动连接

android按键操作

常用按键的keycode

KEYCODE_HOME(home键):3
KEYCODE_BACK(back键):4
KEYCODE_SEARCH(搜索键):84
KEYCODE_ENTER(回车键):66
KEYCODE_MENU(菜单键):82
KEYCODE_POWER(电源键):26
KEYCODE_NOTIFICATION(通知键):83 
KEYCODE_CALL(拨号键):5
KEYCODE_ENDCALL(挂机键):6
...

点击按键

driver.press_keycode(keycode, metastate=None, flags=None)
driver.keyevent(keycode, metastate=None)

driver.press_keycode(3)    # 点击home键

长按按键

driver.long_press_keycode(self, keycode, metastate=None, flags=None)
driver.long_press_keycode(3)  # 长按home键

模拟手势点击坐标点操作

tap函数方法介绍

driver.tap(positions, duration=None)
模拟手指(最多支持5个手指)点击某个特定位置并保持一定时间

  • positions:坐标位置,列表list类型,每个对象是元组tuple类型(x, y)。
    • positions长度,最小为1,最大为5,即格式可为: [(x1, y1), (x2, y2), (x3, y3), (x4, y4), (x5, y5)]。
  • duration:持续时间,单位ms,默认为None。
    • duration=None表示仅执行点击动作;duration!=None表示执行长按点击动作,维持duration时间后再释放;

获取元素坐标方法

  • 通过元素的bounds值来获取点击坐标:
    元素的bounds值格式为 [x1, y1][x2, y2],x1和y1为元素的左上角位置,x2和y2为元素的右下角位置。

    但赋值给positions参数,需要将格式更改一下,改为 [(x1, y1), (x2, y2)]

  • 手动获取元素坐标
    机器进入“开发者选项”,开启“指针位置”,手动点击元素从而获取元素的坐标

案例

# 长按点击元素坐标,同时保持500ms再释放
driver.tap( [(204, 358), (790, 496)], 500)
driver.press_keycode(4)
driver.tap([(204, 358)], 500)
driver.press_keycode(4)
# 点击元素坐标
driver.tap([(204, 358), (790, 496)])
driver.press_keycode(4)
driver.tap([(204, 358)])

滑动操作

swipe和flick函数方法介绍

driver.swipe(start_x, start_y, end_x, end_y, duration=None)

将屏幕从一个点滑动到另一个点

  • start_x:滑动起始点的x轴坐标
  • start_y:滑动起始点的y轴坐标
  • end_x:滑动结束点的x轴坐标
  • end_y:滑动结束点的y轴坐标
  • duration:滑动的持续时间,单位ms

driver.flick(start_x, start_y, end_x, end_y)

将屏幕从一个点快速滑动到另一个点

swipe封装

    def swipe_left(self):
        """向左滑动屏幕"""
        size = self.get_screen_size()
        x1 = int(size[0] * 0.95)
        x2 = int(size[0] * 0.25)
        y = int(size[1] * 0.5)
        self.driver.swipe(x1, y, x2, y, 1000)  # 滑动持续时间1秒

    def swipe_right(self):
        """向右滑动屏幕"""
        size = self.get_screen_size()
        x1 = int(size[0] * 0.25)
        x2 = int(size[0] * 0.95)
        y = int(size[1] * 0.5)
        self.driver.swipe(x1, y, x2, y, 1000)  # 滑动持续时间1秒

    def swipe_up(self):
        """向上滑动屏幕"""
        size = self.get_screen_size()
        x = int(size[1] * 0.5)
        y1 = int(size[0] * 0.95)
        y2 = int(size[0] * 0.25)

        self.driver.swipe(x, y1, x, y2, 1000)  # 滑动持续时间1秒

    def swipe_down(self):
        """向下滑动屏幕"""
        size = self.get_screen_size()
        x = int(size[1] * 0.5)
        y1 = int(size[0] * 0.25)
        y2 = int(size[0] * 0.95)

        self.driver.swipe(x, y1, x, y2, 1000)  # 滑动持续时间1秒

app操作

app的安装、卸载、判断

  • 安装app
    driver.install_app(app_path, **options)

    • app_path:安装app的路径;
    • **options:安装app的其他设置参数,如replace、timeout、allowTestPackages、useSdcard、grantPermissions参数;
      • replace:若app已存在于测试机中,是否重新安装,默认为True;
      • timeout:等待安装完成的时间,默认为60000ms;
      • allowTestPackages:是否允许将安装包标记为测试,默认为False;
      • useSdcard:是否使用SD卡安装app,默认为False;
      • grantPermissions:安装完成后是否自动授予Android6+上的应用权限,默认为False;
  • 判断app是否已安装
    driver.is_app_installed(bundle_id)

    • bundle_id:要查询的应用程序的ID信息,可用package来判断
  • 卸载app
    driver.remove_app(app_id, **options)

    • app_id:要卸载的应用程序的ID信息
    • **options:卸载app的其他设置参数,如keepData、timeout参数;
      • keepData:卸载app后是否保留应用程序数据和缓存,默认为False;
      • timeout:等待卸载完成的时间,默认为20000ms;

app后台运行、启动、重置、关闭、终止操作

  • 启动desired capabilities参数中的应用
    driver.launch_app()
  • 关闭desired capabilitied参数中运行的应用程序
    driver.close_app()
  • 将设备当前的应用程序置于后台运行,保持seconds秒后再重新回到前台运行
    driver.background_app(seconds)
    • seconds:后台运行的时间,单位s
  • 重置设备当前的应用程序,将程序恢复到默认
    driver.reset()
  • 如果某个应用程序app_id正在运行,则终止该应用程序
    driver.terminate_app(app_id, **options)
    • app_id:要终止的应用程序的ID信息
    • **options:要终止的应用程序的其他设置参数,如keepData、timeout参数;
      • timeout:等待时间默认为500ms
  • 启动某个app
    driver.start_activity(app_package, app_activity, **opts)
    • app_package:启动应用的包名
    • app_activity:启动的activity
    • **opts:其他可能需要添加的参数,如app_wait_package、app_wait_activity、intent_action......
      • app_wait_package:等待某个应用的包名出现
      • app_wait_activity:等待某个应用的界面出现

截图操作

driver.get_screenshot_as_file(filename)

  • filename:保存截图的路径+截图名称

若filename不是以.png结尾,则也会执行截图操作,但会有警告提示,故建议一般使用.png结尾的截图。
若截图成功,则返回True;若出现IOError错误则返回False。

截图封装

    def get_screen_shot(self, module):
        t = time.strftime("%Y-%m-%d_%H_%M_%S")
        image_file = file_path("screenshots", f"{module}_{t}.png")
        logging.info(f'【{module}】截图:{image_file}')
        try:
            self.driver.get_screenshot_as_file(image_file)
        except Exception as e:
            print(e)

滚动元素操作

driver.scroll(origin_el, destination_el, duration=None)
从origin_el元素滚动到destination_el元素
界面为上下滑动:origin_ele在destination_el元素上面时,则执行向下滚动;origin_ele在destination_el元素下面时,则原始元素会滚动到目标元素位置。
界面为左右滑动:origin_ele在destination_el元素左边时,则先执行向右滚动再执行向左滚动;origin_ele在destination_el元素右边时,则先执行向左滚动再执行向右滚动。
注:需要这两个元素在当前界面上存在,否则会报错。

拖拽元素操作

driver.drag_and_drop(origin_el, destination_el)
将origin_el元素拖拽到destination_el元素位置
注:&&需要元素支持拖拽操作&&,比如,桌面icon的拖拽操作

ele1 = driver.find_element_by_xpath("//*[@content-desc='天气']")
ele2 = driver.find_element_by_xpath("//*[@content-desc='安全中心']")
driver.drag_and_drop(ele1, ele2)

打开通知栏操作

driver.open_notifications()

获取连接设备的sessions

curl http://127.0.0.1:4723/wd/hub/sessions | awk -F\"'{PRINT $8}'

使用sessions模拟请求appium

curl -H "Content-Type:application/json;charset=UTF-8\ http://127.0.0.1:4723/wd/hub/session/${sessions}/elements\--data-binary '{"using":"xpath","value"://*}'

adb获取设备uiautomator

adb shell uiautomator dump

ADB操作设备adb shell input

adb输入数据

adb shell input text 123

adb滑动页面

adb shell input swipe 200 500 200 800

posted @ 2024-02-02 14:11  三叔测试笔记  阅读(33)  评论(0编辑  收藏  举报
返回顶部 跳转底部