appium安卓环境使用记录总结

ubuntu环境下安装appium

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt -y install nodejs
cnpm  install -g appium 
sudo cnpm  install -g appium 

确定包和参数

adb shell dumpsys activity recents | grep 'intent={'|grep 'tv.danmaku.bili'
# cfzq
adb shell dumpsys activity recents | grep 'intent={'|grep 'cfzq.lezhuan'

手动载入截屏

桌面新建 test.bat文件,添加五行代码,内容如下:

adb shell uiautomator dump /sdcard/app.uix
adb pull /sdcard/app.uix ./app.uix             # 此处输入任意自己本地路径

adb shell screencap -p /sdcard/app.png 
adb pull /sdcard/app.png ./app.png             # 此处输入任意自己本地路径
保存为bat文件后,打开手机,进入自己想要定位的页面,运行新建的 test.bat 
再运行uiautomatorviewer.bat,点击左上角的open按钮,分别选择 test.bat里输入的本地存储路径。
此时能成功获取手机页面的截图。
通用方案为万能方法,基本都能成功,缺点是每进入一个新的页面都需要执行一下test.bat,并在uiautomatorviewer 中导入。

关于appium定位元素

# appium的webdriver提供了11种元素定位方法,在selenium的基础上扩展了三个,可以在pycharm里面输入driver.find_element_by然后会自动匹配出来
#通过id定位成功
driver.find_element_by_id("com.xyh.commerce:id/ll_personal").click()


#tap是模拟手指点击,一般页面上元素.语法有两个参数,第一个是positions,是list类型最多五个点,duration是持续时间,单位毫秒
#通过tap定位成功
driver.tap([(600,1205)],300)


#通过xpath定位
driver.find_element_by_xpath("//*[@resource-id='com.xyh.commerce:id/ly_main_tab_bottom']//android.widget.LinearLayout[3]").click()


# 通过android_uiautomator定位
# 通过id定位
my = 'new UiSelector().resourceId("com.xyh.commerce:id/ll_personal")'
driver.find_element_by_android_uiautomator(my).click()

# 通过text定位
# 1.通过text文本定位语法
new UiSelector().text("text文本")
# 2.文本比较长的时候,可以用textContains模糊匹配,只要文本包含匹配内容就可以了。
new UiSelector().textContains("包含text文本")
# 3.textStartsWith是以某个文本开头的匹配
new UiSelector().textStartsWith("以text文本开头")
# 4.正则匹配textMatches,这个需要配合正则表达式,就不举例了。
new UiSelector().textMatches("正则表达式")


# class属性一般不唯一,多半用在复数定位,className复数定位
loc_class = 'new UiSelector().className("android.widget.TextView")'
driver.find_elements_by_android_uiautomator(loc_class)[2].click()


# 组合定位,一般组合用id,class,text这三个属性会比较好一点
# id+class 属性组合
id_class = 'resourceId("com.xyh.commerce:id/ll_personal").className("android.widget.LinearLayout")'
driver.find_element_by_android_uiautomator(id_class).click()


# 父子定位childSelector
# 有时候不能直接定位某个元素,但是它的父元素很好定位,这时候就先定位父元素,通过父元素找儿子。
son = 'resourceId("com.xyh.commerce:id/ll_personal").childSelector(text("我的"))'
driver.find_element_by_android_uiautomator(son).click()


# 兄弟定位fromParent
# 有时候父元素不好定位,但是跟他相邻的兄弟元素很好定位,这时候就可以通过兄弟元素,找到同一父级元素下的子元素。
brother = 'resourceId("com.xyh.commerce:id/img_personal").fromParent(text("我的"))'
driver.find_element_by_android_uiautomator(brother).click()
global driver
# 元素定位
driver.find_element_by_id("id")   # id定位
driver.find_element_by_name("name")  # name定位
driver.find_element_by_link_text("text")  # 链接名定位
driver.find_element_by_partial_link_text("text")  # 通过元素部分可见链接文本定位
driver.find_element_by_tag_name("name")  # 通过查找html的标签名称定位元素
driver.find_element_by_xpath("xpath")  # 路径定位
driver.find_element_by_class_name("android.widget.LinearLayout")  # 类名定位
driver.find_element_by_css_selector("css") # css选择器定位

# 元素集合复数定位
driver.find_elements_by_id("id")  # id元素集合
driver.find_elements_by_name("name") # name元素集合
driver.find_elements_by_link_text("text") # 链接名元素集合
driver.find_elements_by_partial_link_text("text") # 部分元素可见链接集合
driver.find_elements_by_tag_name("name")  # html标签名集合
driver.find_elements_by_xpath("xpath")  # 路径定位集合
driver.find_elements_by_class_name("android.widget.LinearLayout")  # 类名定位集合
driver.find_elements_by_css_selector("css") # css选择器定位集合

# 输入框输入
driver.element.send_keys("中英")

# 锁定屏幕
driver.lock(5)

# 把当前应用置于后台
driver.background_app(5)

# 收起键盘
driver.hide_keyboard()

# 打开一个应用或者activity,仅安卓端
driver.start_activity('com.example.android.apis', '.Foo')

# 打开下拉通知栏 仅Android
driver.open_notifications()

# 拖动元素,将元素origin_el拖到目标元素destination_el
driver.drag_and_drop(self, origin_el, destination_el):

# 检查app是否已安装
driver.is_app_installed('com.example.android.apis')

# 安装应用到设备
driver.install_app('path/to/my.apk')

# 删除应用
driver.remove_app('com.example.android.apis')

# 模拟设备摇晃
driver.shake()


# 关闭应用
driver.close_app()

# 启动 (Launch)
# 根据服务关键字 (desired capabilities) 启动会话 (session) 。请注意这必须在设定 autoLaunch=false 关键字时才能生效。
# 这不是用于启动指定的 app/activities ————你可以使用 start_activity 做到这个效果————
# 这是用来继续进行使用了 autoLaunch=false 关键字时的初始化 (Launch) 流程的。
driver.launch_app()

# 应用重置,相当于重新卸载安装
driver.reset()

# 可用上下文 (context) 列出所有的可用上下文
# 翻译备注:context可以理解为 可进入的窗口 。例如,对于原生应用,可用的context和默认context均为NATIVE_APP。
# 详情可查看对混合应用进行自动化测试
driver.contexts

# 列出当前上下文
driver.current_context

# 切换到默认的上下文 (context)
# 将上下文切换到默认上下文
driver.switch_to.context(None)

# 获取应用的字符串
driver.app_strings

# 按键事件 (Key Event)给设备发送一个按键事件
driver.keyevent(176)

# 获取当前的activity
driver.current_activity

# 触摸动作(TouchAction) / 多点触摸动作(MultiTouchAction)
action = TouchAction(driver)
action.press(element=el, x=10, y=10).release().perform()

# 滑动(Swipe)模拟用户滑动
# 注意:appium滑动规则是x从左到右变大,y从上到下变大
driver.swipe(start=75, starty=500, endx=75, endy=0, duration=800)

# 捏 (Pinch)捏屏幕 (双指往内移动来缩小屏幕)
driver.pinch(element=el)

# 放大 (Zoom)放大屏幕 (双指往外移动来放大屏幕)
driver.zoom(element=el)

# 滑动到某个元素 (Scroll To)
todo: python

# 从设备中拉出文件 (Pull File)
driver.pull_file('Library/AddressBook/AddressBook.sqlitedb')

# 推送文件到设备中去
data = "some data for the file"
path = "/data/local/tmp/file.txt"
driver.push_file(path, data.encode('base64'))

# 断言
Assert.assertEquals("I am a div", div.getText()); //跳转到指定页面并在该页面所以用元素id进行交互

# 检查文本是否符合预期
assertEqual('I am a div', div.text)

# 输入法是否有活动 返回真假
is_ime_active(self):

# 返回当前安卓设备可用的输入法
driver.available_ime_engines(self):

# 激活安卓设备中的制定输入法
driver.activate_ime_engine(self, engine):

# 关闭当前的输入法(android)
driver.deactivate_ime_engine(self):

# 打开安卓设备上的位置定位设置
driver.toggle_location_services()

# 设置设备的经纬度
    :Args:
     - latitude纬度 - String or numeric value between -90.0 and 90.00
     - longitude经度 - String or numeric value between -180.0 and 180.0
     - altitude海拔高度- String or numeric value
用法 driver.set_location(纬度经度高度)

# 点击
element.click()

# 清除元素内容
element.clear()

# 返回元素的文本内容
element.text()

# 提交表单
element.submit(self):

# 元素是否可用
element.is_enabled()

# 元素是否可选
element.is_slected()

# 元素是否可见
element.is_displayed()

# 获取元素的大小(高和宽)
new_size["height"] = size["height"]
new_size["width"] = size["width"]
driver.element.size

# 获取元素左上角的坐标
# 用法 driver.element.location
'''返回element的x坐标, int类型'''
driver.element.location.get('x')
'''返回element的y坐标, int类型'''
driver.element.location.get('y')

# 获取当前元素的截图为Base64编码的字符串
img_b64 = element.screenshot_as_base64

# 执行JS
# 在当前窗口/框架(特指 Html 的 iframe )同步执行 javascript 代码
driver.execute_script('document.title')
# 异步执行代码,其他代码在执行
driver.execute_async_script('document.title')

# 获取当前url
driver.current_url

# 获取页面源
driver.page_source

# 关闭当前窗口
driver.close()


# 关闭应用
driver.quit()

# chrome上进行测试
{
'platformName': 'Android',
'platformVersion': '4.4',
'deviceName': 'Android Emulator',
'browserName': 'Chrome'
}

# 真机测试
{
'automationName': 'Selendroid',
'platformName': 'Android',
'platformVersion': '2.3',
'deviceName': 'Android Emulator',
'app': myApp,
'appPackage': 'com.mycompany.package',
'appActivity': '.MainActivity'
}

# 多点触控
"""
规范中的可用事件有:
* 短按 (press)
* 释放 (release)
* 移动到 (moveTo)
* 点击 (tap)
* 等待 (wait)
* 长按 (longPress)
* 取消 (cancel)
* 执行 (perform)
"""



5.8 服务器参数
Appium 服务器参数

使用方法: node . [标志]
服务器标志

所有的标志都是可选的但是有一些标志需要组合在一起才能生效

<expand_table>
标志 默认值 描述 例子
--shell null 进入 REPL 模式
--localizable-strings-dir en.lproj IOS only: 定位 .strings所在目录的相对路径 --localizable-strings-dir en.lproj
--app null iOS: 基于模拟器编译的 app 的绝对路径或者设备目标的 bundle_id Android: apk 文件的绝对路径--app /abs/path/to/my.app
--ipa null (IOS-only) .ipa 文件的绝对路径 --ipa /abs/path/to/my.ipa
-U, --udid null 连接物理设备的唯一设备标识符 --udid 1adsf-sdfas-asdf-123sdf
-a, --address 0.0.0.0 监听的 ip 地址 --address 0.0.0.0
-p, --port 4723 监听的端口 --port 4723
-ca, --callback-address null 回调IP地址 (默认: 相同的IP地址) --callback-address 127.0.0.1
-cp, --callback-port null 回调端口号 (默认: 相同的端口号) --callback-port 4723
-bp, --bootstrap-port 4724 (Android-only) 连接设备的端口号 --bootstrap-port 4724
-k, --keep-artifacts false 弃用无效trace信息现在保留tmp目录下每次运行前会清除该目录中的信息 也可以参考 --trace-dir 
-r, --backend-retries 3 (iOS-only) 遇到 crash 或者 超时Instrument 重新启动的次数 --backend-retries 3
--session-override false 允许 session 被覆盖 (冲突的话)
--full-reset false (iOS) 删除整个模拟器目录 (Android) 通过卸载应用而不是清除数据重置应用状态 Android session 完成后也会删除应用
--no-reset false session 之间不重置应用状态 (iOS: 不删除应用的 plist 文件 Android: 在创建一个新的 session 前不删除应用)
-l, --pre-launch false 在第一个 session 预启动应用 (iOS 需要 --app 参数Android 需要 --app-pkg  --app-activity)
-lt, --launch-timeout 90000 (iOS-only) 等待 Instruments 启动的时间
-g, --log null 将日志输出到指定文件 --log /path/to/appium.log
--log-level debug 日志级别; 默认 (console[:file]): debug[:debug] --log-level debug
--log-timestamp false 在终端输出里显示时间戳
--local-timezone false 使用本地时间戳
--log-no-colors false 不在终端输出中显示颜色
-G, --webhook null 同时发送日志到 HTTP 监听器 --webhook localhost:9876
--native-instruments-lib false (IOS-only) iOS 内建了一个怪异的不可能避免的延迟我们在 Appium 里修复了它如果你想用原来的你可以使用这个参数
--app-pkg null (Android-only) 你要运行的apk的java包 (例如 com.example.android.myApp) --app-pkg com.example.android.myApp
--app-activity null (Android-only) 打开应用时启动的 Activity 的名字(比如 MainActivity) --app-activity MainActivity
--app-wait-package false (Android-only) 你想等待的 Activity 的包名(比如 com.example.android.myApp) --app-wait-package com.example.android.myApp
--app-wait-activity false (Android-only) 你想等待的 Activity 名字(比如 SplashActivity) --app-wait-activity SplashActivity
--android-coverage false (Android-only) 完全符合条件的 instrumentation  作为命令 adb shell am instrument -e coverage true -w  -w 的参数 --android-coverage com.my.Pkg/com.my.Pkg.instrumentation.MyInstrumentation
--avd null (Android-only) 要启动的 avd 的名字
--avd-args null (Android-only) 添加额外的参数给要启动avd --avd-args -no-snapshot-load
--device-ready-timeout 5 (Android-only) 等待设备准备好的时间以秒为单位 --device-ready-timeout 5
--safari false (IOS-Only) 使用 Safari 应用
--device-name null 待使用的移动设备名字 --device-name iPhone Retina (4-inch), Android Emulator
--platform-name null 移动平台的名称: iOS, Android, or FirefoxOS --platform-name iOS
--platform-version null 移动平台的版本 --platform-version 7.1
--automation-name null 自动化工具的名称: Appium or Selendroid --automation-name Appium
--browser-name null 移动浏览器的名称: Safari or Chrome --browser-name Safari
--default-device, -dd false (IOS-Simulator-only) 使用instruments自己启动的默认模拟器
--force-iphone false (IOS-only) 无论应用要用什么模拟器强制使用 iPhone 模拟器
--force-ipad false (IOS-only) 无论应用要用什么模拟器强制使用 iPad 模拟器
--language null iOS / Android 模拟器的语言 --language en
--locale null Locale for the iOS simulator / Android Emulator --locale en_US
--calendar-format null (IOS-only) iOS 模拟器的日历格式 --calendar-format gregorian
--orientation null (IOS-only) 初始化请求时使用 LANDSCAPE (横屏) 或者 PORTRAIT (竖屏) --orientation LANDSCAPE
--tracetemplate null (IOS-only) 指定 Instruments 使用的 tracetemplate 文件 --tracetemplate /Users/me/Automation.tracetemplate
--show-sim-log false (IOS-only) 如果设置了 iOS 模拟器的日志会写到终端上来
--show-ios-log false (IOS-only) 如果设置了 iOS 系统的日志会写到终端上来
--nodeconfig null 指定 JSON 格式的配置文件 用来在 selenium grid 里注册 appiumd --nodeconfig /abs/path/to/nodeconfig.json
-ra, --robot-address 0.0.0.0 robot  ip 地址 --robot-address 0.0.0.0
-rp, --robot-port -1 robot 的端口地址 --robot-port 4242
--selendroid-port 8080 用来和 Selendroid 交互的本地端口 --selendroid-port 8080
--chromedriver-port 9515 ChromeDriver运行的端口 --chromedriver-port 9515
--chromedriver-executable null ChromeDriver 可执行文件的完整路径
--use-keystore false (Android-only) 设置签名 apk  keystore
--keystore-path (Android-only) keystore 的路径
--keystore-password android (Android-only) keystore 的密码
--key-alias androiddebugkey (Android-only) Key 的别名
--key-password android (Android-only) Key 的密码
--show-config false 打印 Appium 服务器的配置信息然后退出
--no-perms-check false 跳过Appium对是否可以读/写必要文件的检查
--command-timeout 60 默认所有会话的接收命令超时时间 (在超时时间内没有接收到新命令自动关闭会话) 会被新的超时时间覆盖
--keep-keychains false (iOS)  Appium 启动或者关闭的时候是否保留 keychains (Library/Keychains)
--strict-caps false 如果所选设备是appium不承认的有效设备会导致会话失败
--isolate-sim-device false Xcode 6存在一个bug那就是一些平台上如果其他模拟器设备先被删除时某个特定的模拟器只能在没有任何错误的情况下被建立这个选项导致了Appium不得不删除除了正在使用设备以外其他所有的设备请注意这是永久性删除你可以使用simctl或xcode管理被Appium使用的设备类别
--tmp null 可以被Appium用来管理临时文件的目录绝对路径),比如存放需要移动的内置iOS应用程序 默认的变量为 APPIUM_TMP_DIR  *nix/Mac  /tmp 在windows上使用环境便令 TEMP 设定的目录
--trace-dir null 用于保存iOS instruments trace的 appium 目录是绝对路径 默认为 <tmp dir>/appium-instruments
--intent-action android.intent.action.MAIN (Android-only) 用于启动 activity 的intent action --intent-action android.intent.action.MAIN
--intent-category android.intent.category.LAUNCHER (Android-only) 用于启动 activity 的intent category --intent-category android.intent.category.APP_CONTACTS
--intent-flags 0x10200000 (Android-only) 启动 activity 的标志 --intent-flags 0x10200000
--intent-args null (Android-only) 启动 activity 时附带额外的 intent 参数 --intent-args 0x10200000
--suppress-adb-kill-server false (Android-only) 如果被设定阻止Appium杀掉adb实例
# coding:utf-8
from appium import webdriver
from time import sleep
desired_caps = {
                'platformName': 'Android',
                'deviceName': '127.0.0.1:62001',
                'platformVersion': '4.4.2',
                'appPackage': 'com.baidu.yuedu',
                'appActivity': 'com.baidu.yuedu.splash.SplashActivity'
                }
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)

sleep(5)
# 点弹出框去看看
driver.tap([(374, 831), (654, 906)], 500)

# 返回上一页
driver.back()
sleep(2)

# 点右上角搜素按钮
driver.tap([(615, 52), (690, 146)], 500)

版权声明:除特别注明外,本站所有文章均为王晨曦个人站点原创

转载请注明:出处来自王晨曦个人站点 » appium安卓环境使用记录总结

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

  1. vyivyshrjt 说道:

    出发地 avyivyshrjt vyivyshrjt http://www.g0tl800l6kgu8o1422ne16j04zog6fp9s.org/ [url=http://www.g0tl800l6kgu8o1422ne16j04zog6fp9s.org/]uvyivyshrjt[/url]