【Appium】 课程全笔记(录播+直播课)链接:
Appium基础3(手势操作和uiautomator查找元素)
Appium的触屏操作
滑动小案例
- 进入雪球应用
- 再主页从下往上滑动
- 避免使用坐标(代码用获取屏幕的长宽来解决这个问题)
代码
from time import sleep
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
class TestFind():
def setup(self):
self.desire_cap= {
"platformName":"android",
"deviceName":"127.0.0.1:7555",
"appPackage":"com.xueqiu.android",
"appActivity":".view.WelcomeActivityAlias",
"noReset":"true",
"unicodeKeyboard":True
}
self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
self.driver.implicitly_wait(5)
def test_search(self):
"""
1.进入雪球应用
2.再主页从下往上滑动
3.避免使用坐标
:return:
"""
#由于雪球真的是太慢了,所以睡10秒
sleep(10)
#定义一个TouchAcion对象
aciton=TouchAction(self.driver)
#获取整个屏幕的右下角的坐标
window_rect=self.driver.get_window_rect()
#提取屏幕的最大的宽
width=window_rect["width"]
#提取屏幕的最大的高度
height=window_rect['height']
#x的坐标定义为最大宽的一半,也就是中心的x坐标
x1=int(width/2)
#定义起始的y坐标,在4/5的底部位置
y_start=int(height* 4/5)
#定义终点的y坐标,在1/5顶部的位置,这样就可以模拟从下往上滑动的动作
y_end=int(height* 1/5)
#先press点击初始的坐标,然后按住不放等2秒再move_to到终点坐标,然后再release()释放坐标点,用perform()去执行一系列action操作
aciton.press(x=x1,y=y_start).wait(2000).move_to(x=x1,y=y_end).release().perform()
#重复两次,看的效果更明显
aciton.press(x=x1, y=y_start).wait(2000).move_to(x=x1, y=y_end).release().perform()
aciton.press(x=x1, y=y_start).wait(2000).move_to(x=x1, y=y_end).release().perform()
sleep(3)
滑动多点解锁
- 得下载一个叫手势密码锁的app,百度一下有
- 进入解锁的页面
- 设置解锁密码为一个7字
- 意外发现appium可以指定去不同的初始的activity,好像也是看应用的
代码
from time import sleep
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy as By
from appium.webdriver.common.touch_action import TouchAction
class TestFind():
def setup(self):
self.desire_cap = {
"platformName": "android",
"deviceName": "127.0.0.1:7555",
"appPackage": "cn.kmob.screenfingermovelock",
"appActivity": "com.samsung.ui.MainActivity",
"noReset": "true"
}
self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", self.desire_cap)
self.driver.implicitly_wait(5)
def test_search(self):
"""
1.进入解锁的页面
2.设置解锁密码为一个7字
3.意外发现appium可以指定去不同的初始的activity,好像也是看应用的
:return:
"""
sleep(3)
#定义一个TouchAcion对象
aciton=TouchAction(self.driver)
#找到7个坐标点,通过连续的press,wait,move_to,最后释放手势release(),然后perform()执行即可
aciton.press(x=142,y=190).wait(200).move_to(x=408,y=190).wait(200).move_to(x=678,y=190).wait(200).move_to(x=678,y=464) \
.wait(200).move_to(x=678,y=740).release().perform()
sleep(2)
uiautomator查找元素
- 用法网站:
优缺点
- 优点
- xpath定位速度慢
- uiautomator是Android的工作引擎,速度快
- 滚动查找很方便
- 缺点
- 表达式书写复杂,容易写错IDE没有提示
定位方式
- 通过resource-id定位
- 通过classname定位
- 通过content-desc丁文
- 通过文本丁文
- 组合定位
- 通过父子关系定位
用法
- driver.find_element_by_android_uiautomator(“表达式”)
- 注:外层要用单引号,内层的字符串用双引号,因为本来就是java,java双引号才表示字符串
- 通过文本定位
- new UiSelector().text(“text文本”)
- 通过textContains模糊匹配
- new UiSelector().textContains(“text文本”)
- 通过某个文本开头匹配
- new UiSelector().textStartWith(“text文本”)
- 正则表达式匹配
- new UiSelector().textMatches(“text文本”)
- 组合定位
- 比如id与text的属性组合:driver.find_element_by_android_uiautomator(‘new UiSelector().resourceId(“com.xueqiu.android:id/login_account”).text(“我的”)’)
- 父子关系定位:childSelector,先定位到父类,再用childSelector来定位子类
- driver.find_element_by_android_uiautomator(‘new UiSelector().resourceId(“com.xueqiu.android:id/login_account”).childSelector(text(“股票”))’)
- 兄弟定位:fromParent
- driver.find_element_by_android_uiautomator(‘new UiSelector().resourceId(“com.xueqiu.android:id/login_account”).fromParent(text(“股票”))’)
代码
from time import sleep
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
class TestFind():
def setup(self):
self.desire_cap= {
"platformName":"android",
"deviceName":"127.0.0.1:7555",
"appPackage":"com.xueqiu.android",
"appActivity":".view.WelcomeActivityAlias",
"noReset":"true",
"unicodeKeyboard":True
}
self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
self.driver.implicitly_wait(5)
def test_search(self):
"""
1.打开雪球app
2.点击我的,进入到个人信息页面
3.点击登录,进入到登录页面
4.输入用户名,输入密码
5.点击登录
6.弹出手机号输入失败的提示,并assert这个提示对不对
:return:
"""
#雪球太慢了,只能10秒了,懒得用显示等等
sleep(10)
#在首页找到我的元素,然后点击
self.driver.find_element_by_android_uiautomator('new UiSelector().text("我的")').click()
#不睡2秒回导致下一个页面的元素刷新太快识别不到
sleep(2)
#识别账号密码登录的元素,然后点击
self.driver.find_element_by_android_uiautomator('new UiSelector().text("帐号密码登录")').click()
#不睡2秒回导致下一个页面的元素刷新太快识别不到
sleep(2)
#输入账号名为tongtong
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/login_account")').send_keys("tongtong")
#输入密码为tongtong
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/login_password")').send_keys("tongtong")
#不睡2秒回导致下一个页面的元素刷新太快识别不到
sleep(2)
#点击登录按钮
self.driver.find_element_by_android_uiautomator('new UiSelector().text("登录")').click()
#不睡2秒回导致下一个页面的元素刷新太快识别不到
sleep(2)
#找到错误提示框,里面有一个确定的元素
login_incorrect=self.driver.find_element_by_android_uiautomator('new UiSelector().text("确定")')
#当确定的元素可见,表示登录失败,用例pass
assert login_incorrect.is_displayed()
滑动元素查找
- 有一些页面有持续滑动的能力,比如微博,没有分页,可以一直滑动,uiautomator提供了滑动的很好的方法
- driver.find_element_by_android_uiautomator(‘new UiScrollable(new UiSelector().’
‘scrollable(true).instance(0)).’
‘scrollIntoView(new UiSelector().textContains(“病人”).’
‘instance(0));’).click() - 注意:虚拟机和真机不一样,有时候真机的滑动是ok的,有时候虚拟机的不ok
代码
from time import sleep
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
class TestFind():
def setup(self):
self.desire_cap= {
"platformName":"android",
"deviceName":"127.0.0.1:7555",
"appPackage":"com.xueqiu.android",
"appActivity":".view.WelcomeActivityAlias",
"noReset":"true",
"unicodeKeyboard":True
}
self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
self.driver.implicitly_wait(5)
def test_search(self):
"""
0.你的雪球app先关注一个人,然后往下滑,找到一个关键字,用textContains来模糊匹配
1.打开雪球app
2.点击关注,让屏幕往下滑,直到找到病人的模糊匹配的text元素后点击
:return:
"""
#雪球太慢了,只能10秒了,懒得用显示等等
sleep(10)
#点击关注的元素
self.driver.find_element_by_android_uiautomator('new UiSelector().text("关注")').click()
#睡4秒,怕跳转页面太快,搜索不到元素
sleep(4)
self.driver.find_element_by_android_uiautomator('new UiScrollable(new UiSelector().'
'scrollable(true).instance(0)).'
'scrollIntoView(new UiSelector().textContains("病人").'
'instance(0));').click()
sleep(4)