appuim+python常遇到的问题
'''
appuim使用过程中常见的问题
'''
import time
一、内嵌H5定位
1/在web自动化中我们会遇见frame的问题,在遇见这些内嵌的标签后我们需要做的就是切换窗口,
那么在app自动化测试也有类似的情况就是我们经常看见的内嵌html,在我们原生的app中增加一个由html做成的页面;
2/需要切换contexts那么就需要获取页面的所有contexts,代码实现:
webview = driver.contexts
driver.switch_to.context(webview[1])
driver.find_element_by_link_text('PHP').click()
二、 滑动定位
1/在app自动化中我们经常会遇见一个问题,我们需要查找的元素不在当前可展示的屏幕,至于在什么地方我们不知道
,如果这个时候我们一直使用在当前页面查找,那么系统就会报错,为了解决这个问题我们就需要使用滑动查找
2/在appium中滑动我们所需要使用的方法就是swipe函数,至于往哪个方向滑动就是看我们里面的x,y的值,如果我们需要下往上滑动那么我们就应该是:
driver.swipe(x1,y1,x2,y2,t)
优化方案:
x = driver.get_window_size()['width']
y = driver.get_window_size()['height']
driver.swipe(x*0.1,y*0.1,x*0.6,y*0.7,t)
三、Toast提示信息(一闪而逝):
1、要获取 Toast 信息要满足以下四个要求:
Appium server 版本 1.6.3+才支持 Toast 获取。(而 Appium Server 1.6.3 没有可视化界面,解决方案:下载 Appium-desktop-Setup-1.4.1-ia32.exe)。
代码中必须指定 automationName 为:UIAutomator2
UIAutomator2 只支持安卓版本 5.0+
因此,因为他们的最高支持安卓版本为 4.4.2,可以使用 genymotion 模拟器。
要求安装 jdk1.8 64 位及以上。配置其环境变量 JAVA_HOME 和 path。
2、实现:
def toast_exist(self, toastmessage):
toast_loc = ("xpath", "//*[contains(@text,'%s')]" % toastmessage)
try:
WebDriverWait(self.driver,5,0.2).until(EC.presence_of_element_located(toast_loc))
driver.find_element_by_xpath(toast_loc).text
return True
except:
四、对屏幕的持续操作TouchAction()
Touch Action包含一些列操作,比如按压、长按、点击、移动、暂停。由着些不同操作可以组成一套动作。使用TochAction需要先导入对应的模块
from appium.webdriver.common.touch_action import TouchAction
方法:
按压:press() 开始按压一个元素或坐标点(x,y):TouchAction(driver).press(x=0,y=308)
长按:longPress() 开始按压一个元素或坐标点(x,y)。 相比press()方法,longPress()多了一个入参,既然长按,得有按的时间吧。duration以毫秒为单位
TouchAction(driver).long_press(x=0,y=0,duration=1000)
点击:tap() 对一个元素或控件执行点击操作:TouchAction(driver).tap(x=0,y=0)
移动:move_to() 将指针从上一个点移动到指定的元素或点:TouchAction(driver).move_to(x=0,y=0)
暂停(等待):Wait()暂停脚本的执行,单位为毫秒
释放:release() 结束的行动取消屏幕上的指针
执行:perform() 执行的操作发送到服务器的命令操作:TouchAction(driver).press(x=0,y=308).release().perform()
连续操作:
TouchAction(driver).press(x=212, y=296).wait(100)\
.move_to(x=148, y=0).wait(100)\
.move_to(x=148,y=0).wait(100)\
.move_to(x=-148,y=148).wait(100)\
.move_to(x=-148,y=148).wait(100)\
.move_to(x=148,y=0).wait(100)\
.move_to(x=148,y=0).wait(100) \
.release().wait(200).perform()
//滑动验证码的实现
五、截图:
1、save_screenshot() 该方法直接保存当前屏幕截图到当前脚本所在文件位置:
driver.save_screenshot('login.png')
2、get_screenshot_as_file(self, filename)将截图保留到指定文件路径:
driver.get_screenshot_as_file('./images/login.png')
六、时间等待:
1、强制等待:time.sleep()
2、隐式等待:driver.implicitly_wait(20)::
WebDriver提供的针对driver级别的适用整个生命周期的等待方法,
该等待是全局设置,因而只需在实例化driver后设置一次即可。从等待作用上看,是可以满足需要的,但是考虑到实际应用场景,
driver要等待的元素和脚本要操作的元素未必相同,也就是说,脚本要操作的元素已经出现,但因为设置了全局等待,driver也会继续等待
页面上其他无关元素,直至整个页面加载完毕。因而,与显式等待相比,可能出现无效等待的情况。
3、显式等待:WebDriverWait(driver, 3).until(lambda x: x.find_element_by_id())
WebDriver提供的针对元素级别的、灵活、智能的等待方法,通过配合until()、until_not()、ExpectedCondition等条件的使用,
默认每500ms检查一次条件状态,可以及时将脚本从等待中唤醒,避免无效等待,在实际应用中推荐使用该方法
4、等待activity:获取当前页面的出现时间然后进行等待,设置最大时间
ac = driver.current_activity
driver.wait_activity(".base.ui.MainActivity", 30)
七、Xpha定位的实现
1、如果元素text是唯一的,可以通过text文本定位://*[@text=’text文本属性’]
driver.find_element_by_xpath("//*[@text='文本内容,此处用的是完全匹配']").click()
2、如果元素id是唯一的,也可以id属性定位://*[@resource-id=’id属性’]
driver.find_element_by_xpath("//*[@resource-id='com.taobao.taobao:id/tv_scan_text']").click()
driver.find_element_by_xpth("//*[@resource-id='com.taobao.taobao:id/tv_scan_text'][@text='文本内容,此处用的是完全匹配']").click()
3、class属性唯一的话,同样可以通过class属性定位,有两种方法:
第一种: //class属性 :
driver.find_element_by_xpath("//android.widget.EditText").click()
第二种: //*[@class=’class属性’]
driver.find_element_by_xpath("//*[@class='android.widget.EditText']").click()
4、通过content-desc属性定位://*[@content-desc=’desc的文本’]
driver.find_element_by_xpath("//*[@content-desc='帮助']").click()
5、contains模糊定位: //[contains(@text(), ‘这里是模糊匹配的文本’)]
contains是模糊匹配的定位方法,对于一个元素的id或者text不是固定的,但有一部分是固定的,这种就可以模糊匹配
contains也能模糊匹配id和class属性: //[contains(@resource-id, ‘id属性’)]、//[contains(@clsss, ‘class属性’)]
driver.find_element_by_xpath("//*[contains(@class, 'EditText')]").click()
driver.find_element_by_xpath("//*[contains(@resource-id, 'id/home_searchedit')]").click()
6、组合定位:如果一个元素有2个属性,通过xpath也可以同时匹配2个属性,text, resource-id,class ,index,content-desc这些属性都能任意组合定位
id_class = '//android.widget.EditText[@resource-id="com.taobao.taobao:id/home_searchedit"]'
driver.find_element_by_xpath(id_class).click()
desc_class = '//*[@text="注册/登录" and @index="1"]'
driver.find_element_by_xpath(desc_class).click()
class_text = '//android.widget.EditText[@text="请输入手机号码"]'
driver.find_element_by_xpath(class_text).send_keys("")
id_desc = '//*[contains(@resource-id, "aliuser_menu_item_help") and @content-desc="帮助"]'
driver.find_element_by_xpath(id_desc).click()
7、层级定位
fa_sun = '//*[@resoure-id="com.taobao.taobao:id/home_searchbar"]/android.widget.EditText'
t = driver.find_element_by_xpaths(fa_sun)[0].text
sun_fa1 = '//*[@resource-id="com.taobao.taobao:id/tv_scan_text"]/..'
c = driver.find_element_by_xpath(sun_fa1).tag_name
sun_fa2 = '//*[@resource-id="com.taobao.taobao:id/tv_scan_text"]/parent::*'
d = driver.find_element_by_xpath(sun_fa1).tag_name
sun_fa3 = '//*[@resource-id="com.taobao.taobao:id/tv_scan_text"]/parent::android.widget.LinearLayout'
e = driver.find_element_by_xpath(sun_fa1).tag_name
八、使用uiautomator定位
1、通过text文本定位语法:new UiSelector().text("text文本")
loc_text = 'new UiSelector().text("图书")'
driver.find_element_by_android_uiautomator(loc_text).click()
2、如果文本比较长,可以用textContains模糊匹配:new UiSelector().textContains("包含text文本")
loc_textContains = 'new UiSelector().textContains("图")'
driver.find_element_by_android_uiautomator(loc_textContains).click()
3、同样可以用textStartsWith是以某个文本开头来匹配:ew UiSelector().textStartsWith("以text文本开头")
loc_textStart = 'new UiSelector().textStartsWith("图")'
driver.find_element_by_android_uiautomator(loc_textStart).click()
4、也可以用正则表达式textMatches匹配:new UiSelector().textMatches("正则表达式")
5、resourceId定位:new UiSelector().resourceId("id")
loc_id = 'new UiSelector().resourceId("com.baidu.yuedu:id/webbooktitle")'
driver.find_element_by_android_uiautomator(loc_id).click()
6、className定位:new UiSelector().className("className")
loc_class = 'new UiSelector().className("android.widget.TextView")'
driver.find_element_by_android_uiautomator(loc_class).click()
7、description定位:new UiSelector().description("contenet-des属性")
8、组合定位
id_text = 'resourceId("com.baidu.yuedu:id/webbooktitle").text("小说")'
class_text = 'className("android.widget.TextView").text("图书")'
9、关系定位
父子定位childSelector
son = 'resourceId("com.baidu.yuedu:id/rl_tabs").childSelector(text("小说"))'
driver.find_element_by_android_uiautomator(son).click()
兄弟定位fromParent
brother = 'resourceId("com.baidu.yuedu:id/lefttitle").fromParent(text("图书"))'
driver.find_element_by_android_uiautomator(brother).click()
常用的一些方法:
from appium import webdriver
from selenium.webdriver.common.touch_actions import TouchActions
import time
caps = {}
caps["platformName"] = "Android"
caps["platformVersion"] = "8.0.0"
caps["deviceName"] = "Phone"
caps["appPackage"] = "com.android.settings"
caps["appActivity"] = ".Settings"
driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
time.sleep(1)
driver.find_element_by_xpath("//android.widget.TextView[@text='Network & Internet']").click()
print(driver.available_ime_engines)
driver.open_notifications()
time.sleep(2)
driver.press_keycode(4)
driver.save_screenshot("new.png")
'''driver.find_element_by_xpath("//android.widget.TextView[@text='Display']").click() #使用xpath方法定位
m = driver.find_element_by_xpath("//android.widget.TextView[@text='Adaptive brightness']")
print(m.get_attribute("className")) #获取元素m的className值 '''
'''
e = driver.find_element_by_android_uiautomator('new UiSelector().className("android.widget.SeekBar")') #使用uiautomator搭配class属性方法定位 控制条
ex = e.location.get('x') #获取元素初始横坐标
ey = e.location.get('y') #获取元素初始纵坐标
#driver.tap([(ex,ey)],500) #用tap方法点击拖动按钮的最左侧起始位置
#driver.tap([(ex+400,ey)],500) #用tap方法横向点击某按钮,ex+400,ey不变
driver.swipe(ex,ey,ex+400,ey,500) #用swipe方法横向拖动某按钮, ey纵坐标不变
time.sleep(1)
driver.press_keycode(4) #按导航返回键'''
'''k = driver.find_element_by_xpath("//android.widget.TextView[@text='Network & Internet']") #定位元素Network & Internet,通过xpath方式
kx = k.location.get('x') #获取元素的x坐标
ky = k.location.get('y') #获取元素的y坐标
driver.tap([(kx,ky)],5000) #长按元素坐标5s
time.sleep(2)
driver.install_app('F:\\soft\\weixin.apk') #安装app,后接apk路径
#driver.remove_app("com.tencent.mm") #删除app(包名)
driver.press_keycode('4') #按返回键
#driver.keyevent('3') #按home键
time.sleep(2)'''
'''
driver.find_element_by_accessibility_id("Search settings").click() #定位并点击click()
#driver.find_element_by_id("android:id/search_src_text").send_keys('wifi') #定位到搜索输入栏,用.send_keys()方法模拟输入文本
#driver.find_element_by_id("android:id/search_src_text") #定位到搜索输入栏
driver.press_keycode(42) #模拟点击键盘上的n
driver.press_keycode(34) #模拟点击键盘上的f
driver.press_keycode(31) #模拟点击键盘上的c
time.sleep(1)
driver.find_element_by_accessibility_id("Clear query").click() #清除文本,用.clear()方法来清除输入文本 通过id方式定位
driver.find_element_by_accessibility_id("Navigate up").click() #点击返回键'''
'''
k = driver.find_element_by_xpath("//android.widget.TextView[@text='Network & Internet']") #定位元素并附值给k
print(k.size) #获取K元素的size,包括height, width
print(driver.get_window_size()) #打印屏幕分辨率
'''
'''time.sleep(2) #强制等待2s
x = driver.get_window_size()['width'] #获取屏幕的宽度
y = driver.get_window_size()['height'] #获取屏幕的高度
driver.swipe(1/2*x, 5/7*y, 1/2*x, 2/7*y, 1000) #从下往上滑动屏幕(5/7->2/7)
time.sleep(2)
driver.close_app() #关闭app
time.sleep(2)
driver.launch_app() #启动app
time.sleep(2)
driver.get_screenshot_as_file('G:\\Kemi\\pic.png') #截取当前屏幕并命名pic.png,然后保存到电脑G:\Kemi下
driver.save_screenshot("newContact.png") #截取当前屏幕并命名pic.png,然后保存到电脑当前目录下'''
time.sleep(2)
x = driver.get_window_size()['width']
y = driver.get_window_size()['height']
driver.swipe(1/2*x, 6/7*y, 1/2*x, 1/7*y, 1000)
time.sleep(1)
driver.find_element_by_xpath("//android.widget.TextView[@text='Support']").click()
try:
driver.find_element_by_id("com.sonymobile.support:id/eula_agree").click()
except Exception as e:
pass
try:
driver.find_element_by_id("com.android.packageinstaller:id/permission_allow_button").click()
except Exception as e:
pass
driver.find_element_by_xpath("//android.widget.ImageView[@resource-id='com.sonymobile.support:id/icon'][@instance='4']").click()