appium(2)简单的demo、元素定位 |
您所在的位置:网站首页 › appium元素定位工具 › appium(2)简单的demo、元素定位 |
目录
appium-录制用例获取包名和activity录制步骤(1)启动appium客户端,默认启动地址 http://127.0.0.1:4723/wd/hub(2)file>New Session Window(3)配置设备信息、包名等,点【Start Session】(4)录制脚本
代码报错
Capability设置重置策略获取安卓udid
手机设置开启开发者模式开启手机指针位置
定位工具:uiautomatorviewer.bat元素定位常用定位方式元素常用方法代码
TouchActions代码
特殊控件toast定位定位代码
uiautomator定位常用表达式组合定位:父子关系定位:滚动页面查找元素代码
踩坑ui automator识别模拟器为横屏Selenium error: Could not parse UiSelector argument: 'com.xueqiu.android:id/tv_search' is not a stringCall to '10' failed
appium-录制用例
获取包名和activity
windows系统 adb shell dumpsys activity |find “mFocusedActivity” 获取当前activity C:\Users\Administrator>adb shell dumpsys activity |find "mFocusedActivity" mFocusedActivity: ActivityRecord{10828b7 u0 com.xueqiu.android/.common.MainActivity t11}adb shell dumpsys window | findstr mCurrentFocus 获取当前activity C:\Users\Administrator>adb shell dumpsys window | findstr mCurrentFocus mCurrentFocus=Window{26c290 u0 com.xueqiu.android/com.xueqiu.android.common.MainActivity} 录制步骤 (1)启动appium客户端,默认启动地址 http://127.0.0.1:4723/wd/hub{ “platformName”: “android”, “deviceName”: “Huawei Mate30”, “appPackage”: “com.xueqiu.android”, “appActivity”: “.view.WelcomeActivityAlias”, “noReset”: “True” } ![]() ![]() 运行效果: Security exception: PID 26038 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package com.xueqiu.android 原因: 安卓手机未开启OEM解锁 解决: 设置>开发者选项>OEM解锁,改为开启 https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md CapabilityDescriptionValuesautomationNameautomation引擎Appium (default), or UiAutomator2, Espresso, or UiAutomator1 for Android, or XCUITest or Instruments for iOS, or YouiEngine for application built with You.i Engineappapp地址/abs/path/to/my.apk or http://myapp.com/app.ipaplatformName手机使用的操作系统iOS, Android, or FirefoxOSplatformVersion操作系统版本e.g., 7.1, 4.4deviceName设备名称iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android Emulator, Galaxy S4udid设备唯一标识符e.g. 1ae203187fc012gnoReset不重置app状态true, falsefullReset重置apptrue, falsedontStopAppOnReset在使用adb启动应用程序之前,不会停止测试应用程序的进程。如果被测试的应用程序是由另一个锚应用程序创建的,设置为false,则允许锚应用程序的进程在使用adb启动测试应用程序期间仍然是活动的。换句话说,当dontStopAppOnReset设置为true时,我们将不会在adb shell am start调用中包含-S标志。省略此功能或将其设置为false后,我们将包含-S标志。默认falsetrue, falsenewCommandTimeout在假定客户机退出并结束会话之前,Appium等待来客户机新命令的时间(以秒为单位)e.g 60单位秒appActivity【安卓】启动的Android活动(页面)的活动(页面)名MainActivity, .SettingsappPackage【安卓】apk包名com.example.android.myApp, com.android.settingsdontStopAppOnReset【安卓】在adb启动应用程序之前,不会停止测试应用程序的进程true or falseskipDeviceInitialization【安卓】跳过设备初始化,包括.安装和运行设置应用程序或设置权限。可用于提高启动性能true or falseunicodeKeyboard【安卓】支持Unicode 输入, 默认为false;切换非英文输入true or falseresetKeyboard【安卓】将键盘重置为其原始状态为falsetrue or falseautoGrantPermissions【安卓】在安装时自动授权app所需要的权限,默认为fasle。如果noReset为 true,此配置不生效。true or falseskipDeviceInitialization【安卓】跳过设备初始化,包括安装和运行设置应用程序或设置权限。可用于提高启动性能,设备已用于自动化,并为下一次自动化做好准备。默认为falsetrue or falseskipUnlock【安卓】在会话创建期间跳过解锁。默认值为falsetrue or falseskipLogcatCapture【安卓】跳过捕捉logcat日志。它可能会提高性能,比如网络。日志相关的命令将无法工作。默认值为false。true or falsesystemPort【安卓】systemPort用于连接到appium-uiautomator2-server或appium-espresso-driver。默认值一般是8200,对于appium-uiautomator2-server,从8200到8299选择一个端口,对于appium- espreso -driver,从8300到8399选择8300。并行运行测试时,必须调整端口以避免冲突。e.g., 8201ignoreUnimportantViews【安卓】调用setCompressedLayoutHierarchy()。忽略一些元素提高运行速度。被忽略的元素将无法找到。默认falsetrue or false 重置策略模拟器 "udid":"127.0.0.1:62001" 真机 "udid":"eaa66aa37d14" 手机设置 开启开发者模式(1)设置>关于手机>连续点击版本号5次以上 (2)设置中,已经出现【开发者选项】 开发者选项—>指针位置,设为开启状态。开启后,顶部会有指针移动坐标,可定位屏幕上的元素的坐标。 ![]() 文档: https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/touch-actions.md 常用方法: 方法释义press按住release释放moveTo移动至tap点击wait等待,单位为mslongPress长按perform执行TouchAction TouchAction().press(el0).moveTo(el1).release()MultiTouch同时按住多个元素 action0 = TouchAction().tap(el) action1 = TouchAction().tap(el) MultiAction().add(action0).add(action1).perform()滚动 driver.execute_script("mobile: scroll", {"direction": "down"}) 代码 # pip install appium-python-client from appium import webdriver import time from appium.webdriver.common.touch_action import TouchAction class TestTouchAction: def setup(self): descrip_cap = { "platformName": "android", "deviceName": "Huawei Mate30", "appPackage": "cn.kmob.screenfingermovelock", "appActivity": "com.samsung.ui.FlashActivity", "noReset": "True", } self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap) self.driver.implicitly_wait(10) def teardown(self): time.sleep(3) self.driver.quit() def test_xueqiu(self): #点击开启手势密码 el1 = self.driver.find_element_by_accessibility_id("手势密码锁") el1.click() # 绘制手势密码 # 以下坐标试用 手机分辨率为540*960 coordinate1 = (90,128) coordinate2 = (272,128) coordinate3 = (450,128) coordinate4 = (272,350) wait_time = 220 #单位为ms毫秒 TouchAction(self.driver).press(x=coordinate1[0],y=coordinate1[1]).wait(wait_time)\ .move_to(x=coordinate2[0],y=coordinate2[1]).wait(wait_time)\ .move_to(x=coordinate3[0],y=coordinate3[1]).wait(wait_time)\ .move_to(x=coordinate4[0],y=coordinate4[1]).wait(wait_time)\ .release().perform() # 点击继续 el2 = self.driver.find_element_by_id("cn.kmob.screenfingermovelock:id/btnTwo") el2.click() # 再次绘制绘制手势密码 TouchAction(self.driver).press(x=coordinate1[0], y=coordinate1[1]).wait(wait_time) \ .move_to(x=coordinate2[0], y=coordinate2[1]).wait(wait_time) \ .move_to(x=coordinate3[0], y=coordinate3[1]).wait(wait_time) \ .move_to(x=coordinate4[0], y=coordinate4[1]).wait(wait_time) \ .release().perform() # 点击确认 el3 = self.driver.find_element_by_id("cn.kmob.screenfingermovelock:id/btnTwo") el3.click()toast 简短消息提示框根据设置的显示时间后自动消失系统级别控件。归属于系统settings。不在app内。例如下图的“验证码已发送”提示语 通过打印页面元素,可以看到toast元素 但是通过class="android.widget.Toast"无法定位到,因此使用Xpath通过文本定位 driver.find_element_by_xpath('//*[@text="验证码已发送"]')注意:Capability设置需加上automationName,才可以定位到 “automationName”:“uiautomator2” 代码 # pip install appium-python-client from appium import webdriver import time from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions from appium.webdriver.common.mobileby import MobileBy class TestXueQiu: def setup(self): des_caps = { "platformName": "android", "deviceName": "Huawei Mate30", "appPackage": "com.xueqiu.android", "appActivity": ".view.WelcomeActivityAlias", "noReset": "True", "unicodeKeyboard":"True", "resetKeyboard":"True", "automationName":"uiautomator2" } self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", des_caps) self.driver.implicitly_wait(10) def teardown(self): time.sleep(3) self.driver.quit() def test_toast(self): # 点击【我的】 self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/tab_name' and @text='我的']").click() # 点击【手机号】登录 self.driver.find_element_by_id('com.xueqiu.android:id/tv_login_phone').click() # 输入手机号码 self.driver.find_element_by_id('com.xueqiu.android:id/register_phone_number').send_keys("18000000000")#任意填个手机号码 # 点击【发送验证码】 self.driver.find_element_by_id('com.xueqiu.android:id/register_code_text').click() # 等待toast元素加载 locator = (MobileBy.XPATH,'//*[@text="验证码已发送"]') WebDriverWait(self.driver,30).until(expected_conditions.presence_of_element_located(locator)) # # 打印当前页面元素树 print(self.driver.page_source) # toast元素 # # 等待toast元素消失 WebDriverWait(self.driver, 30).until_not(expected_conditions.presence_of_element_located(locator)) # 定位"重新获取"验证码按钮,获取文案 text = self.driver.find_element_by_id('com.xueqiu.android:id/register_code_text').text assert "重新获取" in text uiautomator定位https://developer.android.com/reference/android/support/test/uiautomator/UiSelector.html uiautomator是安卓的工作引擎,速度快,但表达式书写复杂。 常用表达式 表达式new UiSelector().reaourceId(“id”)通过id定位new UiSelector().className(“className”)通过className定位new UiSelector().descriptioon(“content-desc”)通过content-desc定位new UiSelector().text(“text”)通过文本定位new UiSelector().textContains(“包含文本”)通过包含文本定位new UiSelector().textStartsWith(“以text开头”)匹配以text开头的元素new UiSelector().textMatches(“正则表达式”)通过正则表达式匹配文本childSelector()父子关系定位fromParent()兄弟关系定位 组合定位: driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/name").text("阿里巴巴")') 父子关系定位: driver.find_element_by_android_uiautomator( 'new UiSelector().resourceId("com.xueqiu.android:id/ll_stock_result_view").childSelector(text("阿里巴巴"))') 滚动页面查找元素 self.driver.find_element_by_android_uiautomator( 'new UiScrollable(new UiSelector().scrollable(true).' 'instance(0)).scrollIntoView(new UiSelector().textContains("财经").' 'instance(0))').click() 代码 # pip install appium-python-client from appium import webdriver import time class TestXueQiu: def setup(self): descrip_cap = { "platformName": "android", "deviceName": "Huawei Mate30", "appPackage": "com.xueqiu.android", "appActivity": ".view.WelcomeActivityAlias", "noReset": "True", "unicodeKeyboard":"True", "resetKeyboard":"True" } self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap) self.driver.implicitly_wait(10) def teardown(self): time.sleep(3) self.driver.quit() def test_check_alibaba(self): # 定位、点击搜索框 # el1 = self.driver.find_element_by_id("com.xueqiu.android:id/tv_search") # resourceId("com.xueqiu.android:id/tv_search") el1 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/tv_search")') el1.click() # 输入搜索关键词 # el2 = self.driver.find_element_by_id("com.xueqiu.android:id/search_input_text") el2 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/search_input_text")') el2.send_keys("阿里巴巴") #点击搜索到的词条 # Xpath定位 # el3 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']") el3 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/name").text("阿里巴巴")') el3.click() # 点击阿里巴巴,进入股票页面 # Xpath定位 # el4 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/stockName' and @text='阿里巴巴']") # el4 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/stockName").text("阿里巴巴")') # 通过搜索结果列表框定位其儿子节点中text为“阿里巴巴”的元素 el4 = self.driver.find_element_by_android_uiautomator( 'new UiSelector().resourceId("com.xueqiu.android:id/ll_stock_result_view").childSelector(text("阿里巴巴"))') el4.click() # 获取当前股价 # el5 = self.driver.find_element_by_id("com.xueqiu.android:id/stock_current_price") el5 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/stock_current_price")') print("阿里巴巴当前股价为:%s"% str(el5.text)) # 判断阿里巴巴股价是否大于200 assert float(el5.text) > 200 def test_scroll_to_article(self): time.sleep(1) # 滚动匹配包含"财经"的文本,并点击 self.driver.find_element_by_android_uiautomator( 'new UiScrollable(new UiSelector().scrollable(true).' 'instance(0)).scrollIntoView(new UiSelector().textContains("财经").' 'instance(0))').click()
解决: 设置模拟器分辨率 Call to ‘10’ failed [elements("-android uiautomator",“new UiSelector().resourceId(‘com.xueqiu.android:id/tv_search’)”)] Error response status: 9, , UnknownCommand - The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource. Selenium error: Could not parse UiSelector argument: ‘com.xueqiu.android:id/tv_search’ is not a string 原因: 定位表达式中使用了单引号 new UiSelector().resourceId(‘com.xueqiu.android:id/tv_search’) 解决: 定位表达式中使用了双引号 new UiSelector().resourceId(“com.xueqiu.android:id/tv_search”) |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |