appium应用之“获取设备信息和设备操作”(android)

一、获取设备信息

1. 获取设备大小

  • driver.get_window_size()
    获取设备的长度和高度,返回值为字典类型,key值为width、height
window_size = driver.get_window_size()
print(window_size)      # {'width': 1080, 'height': 1920}

2. 获取设备上下文信息

  • driver.contexts
    获取所有的上下文信息,返回值为列表类型
  • driver.context
    获取当前上下文,返回值为字符串类型
  • driver.current_context
    获取当前上下文,返回值为字符串类型
# 获取所有的上下文
all_contexts = driver.contexts
print(all_contexts)         # ['NATIVE_APP']
# 获取当前上下文
cur_context = driver.context
print(cur_context)          # NATIVE_APP
cur_context1 = driver.current_context
print(cur_context1)         # NATIVE_APP

3. 获取当前应用的信息

  • driver.current_activity
    获取当前应用的activity信息
  • driver.current_package
    获取当前应用的package信息
app_activity = driver.current_activity
print(app_activity)         # .MainSettings
app_package = driver.current_package
print(app_package)          # com.android.settings

二、设备操作

1. 等待activity出现操作

  • driver.wait_activity(activity, timeout, interval=1)
    等待目标页面出现,若在设置时间内目标页面出现则直接跳出等待,同时返回True; 若超过设置时间目标页面仍未出现则返回False
    activity:目标activity
    timeout:超时时间设置,单位为s
    interval:循环查询的时间间隔,单位为s,默认为1s
    目的:主要用于一些应用启动时界面的activity与进入应用时界面的activity不一致,这样就会存在等待时间,而这个等待时间每次可能不一样,故可通过设置超时来等待。
# 判断10s内是否已成功进入所需的目标activity
desired_caps = {'platformName': 'Android',
                'platformVersion': '8.1',
                'deviceName': 'XXX',
                'automationName': 'Appium',
                'noReset': 'true',
                'unicodeKeyboard': 'true',
                'resetKeyboard': 'true',
                'appPackage': 'com.kugou.android',
                'appActivity': '.app.splash.SplashActivity'
                }
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("超过未进入目标主页面")

2. 退出设备操作

  • driver.quit()
    退出设备并关闭所有相关窗口。

3. 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
    ...
3.1. 点击按键
  • driver.press_keycode(keycode, metastate=None, flags=None)
  • driver.keyevent(keycode, metastate=None)
3.2. 长按按键
  • driver.long_press_keycode(self, keycode, metastate=None, flags=None)
# 点击home键
driver.press_keycode(3)
driver.keyevent(3)
# 长按home键
driver.long_press_keycode(3)

4. 模拟手势点击坐标点操作

4.1. 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时间后再释放;
4.2. 获取元素坐标方法

(1)通过元素的bounds值来获取点击坐标:
元素的bounds值格式为 [x1, y1][x2, y2],x1和y1为元素的左上角位置,x2和y2为元素的右下角位置。
但赋值给positions参数,需要将格式更改一下,改为 [(x1, y1), (x2, y2)]
(2)手动获取元素坐标
机器进入“开发者选项”,开启“指针位置”,手动点击元素从而获取元素的坐标

# 长按点击元素坐标,同时保持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)])

5. 滑动操作

5.1. 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)
    将屏幕从一个点快速滑动到另一个点

5.2. 说明

可用于将整个屏幕或某个元素执行向左、向右、向上、向下滑动;也可用于从某个坐标点滑动到另一个坐标点。
由于测试过程中会不断使用到swipe函数的滑动操作,故可将屏幕或元素向左、向右、向上、向下滑动进行封装,以便下次直接使用。

# 向上滑动屏幕:先获取屏幕的宽度和高度,再将屏幕从下往上滑动
window_size = driver.get_window_size()
start_x = window_size['width'] * 0.5
start_y = window_size['height'] * 0.75
end_y = window_size['height'] * 0.25
driver.swipe(start_x, start_y, start_x, end_y, 500)
# 向上滑动元素:先获取元素的起始坐标、宽度和高度,再将元素从下往上滑动
element = driver.find_element_by_id("android:id/list")
ele_rect = element.rect
start_x1 = ele_rect['x'] + ele_rect['width'] * 0.5
start_y1 = ele_rect['y'] + ele_rect['height'] * 0.75
end_y2 = ele_rect['y'] + ele_rect['height'] * 0.25
driver.swipe(start_x1, start_y1, start_x1, end_y2, 500)
# 直接使用坐标点向上滑动屏幕
driver.swipe(500, 700, 500, 300, 500)
# 快速滑动
driver.flick(start_x, start_y, start_x, end_y)

6. app操作

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

  • driver.is_app_installed(bundle_id):判断app是否已安装
    bundle_id:要查询的应用程序的ID信息,可用package来判断

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

6.2. app后台运行、启动、重置、关闭、终止操作
  • driver.launch_app()
    启动desired capabilities参数中的应用

  • driver.close_app()
    关闭desired capabilitied参数中运行的应用程序

  • driver.background_app(seconds)
    将设备当前的应用程序置于后台运行,保持seconds秒后再重新回到前台运行
    seconds:后台运行的时间,单位s

  • driver.reset()
    重置设备当前的应用程序,将程序恢复到默认

  • driver.terminate_app(app_id, **options)
    如果某个应用程序app_id正在运行,则终止该应用程序
    app_id:要终止的应用程序的ID信息
    **options:要终止的应用程序的其他设置参数,如keepData、timeout参数;
    timeout:等待时间默认为500ms

  • driver.start_activity(app_package, app_activity, **opts)
    启动某个app
    app_package:启动应用的包名
    app_activity:启动的activity
    **opts:其他可能需要添加的参数,如app_wait_package、app_wait_activity、intent_action......
    app_wait_package:等待某个应用的包名出现
    app_wait_activity:等待某个应用的界面出现

# 安装app
driver.install_app("F:\\test.apk")
# 判断app是否已安装
is_installed = driver.is_app_installed("com.tencent.wstt.gt")
print(is_installed)
# 关闭desired capabilities参数中的应用
driver.close_app()
# 启动desired capabilities参数中的应用
driver.launch_app()
# 后台运行设备当前的应用
driver.background_app(5)
# 重置设备当前的应用
driver.reset()
# 卸载应用
driver.remove_app("com.tencent.wstt.gt")
# 终止应用
driver.terminate_app("com.kugou.android")
# 启动某个应用
driver.start_activity("com.kugou.android", ".app.splash.SplashActivity")

7. 截图操作

  • driver.get_screenshot_as_file(filename)
    filename:保存截图的路径+截图名称
    若filename不是以.png结尾,则也会执行截图操作,但会有警告提示,故建议一般使用.png结尾的截图。
    若截图成功,则返回True;若出现IOError错误则返回False。
filename = r"F:\test.png"
driver.get_screenshot_as_file(filename)

8. 滚动元素操作

  • 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元素右边时,则先执行向左滚动再执行向右滚动。
    注:需要这两个元素在当前界面上存在,否则会报错。
ele1 = driver.find_element_by_xpath("//*[@text='壁纸']")
ele2 = driver.find_element_by_xpath("//*[@text='WLAN']")
driver.scroll(ele1, ele2)

9. 拖拽元素操作

  • 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)

10. 打开通知栏操作

  • driver.open_notifications()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容