Python+Appium+Pytest 自动化测试教程
1、滑动操作的场景
移动端应用中的滑动场景,大致有如下几种类型:
-
触摸事件模拟:滑动操作的基本原理是模拟用户触摸屏幕的行为。通过发送一系列的触摸事件,模拟用户按住、滑动和释放的动作,可以实现在屏幕上滑动的效果。
-
坐标计算:滑动操作通常涉及到起始点和终点的坐标计算,起始点表示滑动的起始位置,终点表示滑动的结束位置。这些坐标可以是相对于屏幕或特定元素的坐标。
-
惯性滑动:有些滑动操作在用户释放手指后还会继续滑动一段距离,模拟惯性滑动的效果,这通常需要在滑动过程中模拟逐渐减速的过程。
1、swipe 方法
从一个点滑动到另一个点,可选择持续时间,具有滑动的惯性。需要的参数如下:
- start_x:开始坐标 x。
- start_y:开始坐标 y。
- end_x:结束坐标 x。
- end_y:结束坐标 y。
- duration(可选):滑动持续的时间,默认为 0。
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
class TestSwipe:
def setup_class(self):
'''
完成 capability 设置
初始化 driver
:return:
'''
# 设置 cpability
caps = {
# 设置 app 安装的平台(Android,iOS)
"platformName": "Android",
# 设置 appium 驱动
"appium:automationName": "uiautomator2",
# 设置设备名称
"appium:deviceName": "遥遥领先",
# 设置被测 app 的包名
"appium:appPackage": "com.xxxx.apis",
# 设置被测 app 启动页面的 Activity
"appium:appActivity": ".xxxx"
}
# 初始化 driver
self.driver = webdriver.Remote(
"http://127.0.0.1:4723",
options=UiAutomator2Options().load_capabilities(caps)
)
# 设置全局隐式等待
self.driver.implicitly_wait(5)
def teardown_class(self):
'''
关闭 driver
:return:
'''
self.driver.quit()
def test_swipe_views(self):
# 从一个点滑动到另一个点,可选择持续时间
'''
start_x: 开始坐标 x
start_y: 开始坐标 y
end_x: 结束坐标 x
end_y: 结束坐标 y
duration: 持续时间
'''
# 点击进入 Views 界面
self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'Views').click()
# 获取窗口的宽和高
size = self.driver.get_window_size()
height = size.get('height')
weight = size.get('width')
# 执行滑动操作
self.driver.swipe(
start_x=weight * 0.5,
start_y=height * 0.8,
end_x=weight * 0.5,
end_y=height * 0.2,
duration=2000
)
# 查找 Picker 元素
ele = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'Picker')
# 断言滑动成功 找到元素
assert ele.text == 'Picker'
2、scroll 方法
从一个元素滑动到另一个元素,具有滑动的惯性。需要的参数如下
- origin_el:滑动的起始元素
- destination_el:滑动的结束元素
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
class TestSwipe:
def setup_class(self):
'''
完成 capability 设置
初始化 driver
:return:
'''
# 设置 cpability
caps = {
# 设置 app 安装的平台(Android,iOS)
"platformName": "Android",
# 设置 appium 驱动
"appium:automationName": "uiautomator2",
# 设置设备名称
"appium:deviceName": "遥遥领先",
# 设置被测 app 的包名
"appium:appPackage": "com.xxxx.apis",
# 设置被测 app 启动页面的 Activity
"appium:appActivity": ".xxxx"
}
# 初始化 driver
self.driver = webdriver.Remote(
"http://127.0.0.1:4723",
options=UiAutomator2Options().load_capabilities(caps)
)
# 设置全局隐式等待
self.driver.implicitly_wait(5)
def teardown_class(self):
'''
关闭 driver
:return:
'''
self.driver.quit()
def test_scroll_ele(self):
'''
从一个元素滑动到另一个元素
'''
# 点击进入 Views 界面
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, 'Views'
).click()
# 滑动起始元素
image_btn = self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, 'ImageButton'
)
# 滑动结束元素
button = self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, 'Buttons'
)
# 执行滑动操作
self.driver.scroll(image_btn, button, duration=2000)
# 查找 Picker 元素
ele = self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, 'Picker'
)
assert ele.text == 'Picker'
2、常见控件交互方法(重点)
与 Web 元素操作一样(参考 Selenium Web 元素操作),定位到 APP 控件元素后,可以对控件进行一系列的操作,实现与 APP 交互,比如点击、文本输入、元素属性获取等。
2.1、常见操作
- 点击元素:element.click()
- 点击坐标:driver.tap([(x, y)], 1000)
- 元素中输入内容:element.send_keys(‘appium’)
- 清除元素中内容:element.clear()
2.2、状态判断
- 是否可见 element.is_displayed() 返回 True/False
- 是否可用 element.is_enabled() 返回 True/False
- 是否被选中 element.is_selected() 返回 True/False
2.3、获取元素属性
-
获取元素属性:element.get_attribute()
1.resource-id
2.text
3.class
4.content-desc
5.checkable、checked、clickable、enabled、focusable、focused 等 -
获取元素文本:element.text
-
获取元素坐标:
1.格式:element.location
2.结果:{‘y’: 19,'x: 498} -
获取元素尺寸(高和宽):
1.格式:element.size
2.结果:{‘width’:500,‘height’:22}
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
class TestEleOper:
def setup_class(self):
'''
完成 capability 设置
初始化 driver
:return:
'''
# 设置 cpability
caps = {
# 设置 app 安装的平台(Android,iOS)
"platformName": "Android",
# 设置 appium 驱动
"appium:automationName": "uiautomator2",
# 设置设备名称
"appium:deviceName": "遥遥领先",
# 设置被测 app 的包名
"appium:appPackage": "com.xxxx.apis",
# 设置被测 app 启动页面的 Activity
"appium:appActivity": ".xxxx"
}
# 初始化 driver
self.driver = webdriver.Remote(
"http://127.0.0.1:4723",
options=UiAutomator2Options().load_capabilities(caps)
)
# 设置全局隐式等待
self.driver.implicitly_wait(5)
def teardown_class(self):
'''
关闭 driver
:return:
'''
self.driver.quit()
def test_ele_oper(self):
'''
点击滑动条中心位置
:return:
'''
# 点击 Animation
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, "Animation"
).click()
# 点击 Seeking
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, "Seeking"
).click()
# 查看【RUN】按钮是否显示/是否可点击
run_btn_ele = self.driver.find_element(
AppiumBy.ID, "io.appium.android.apis:id/startButton"
)
print(f"RUN 按钮是否显示 {run_btn_ele.is_displayed()}")
print(f"RUN 按钮是否可用 {run_btn_ele.is_enabled()}")
print(f"RUN 按钮是否可点击 {run_btn_ele.get_attribute('clickable')}")
# 查看【滑动条】是否显示/是否可点击
seek_bar_ele = self.driver.find_element(
AppiumBy.ID, "io.appium.android.apis:id/seekBar"
)
print(f"滑动条是否显示 {seek_bar_ele.is_displayed()}")
print(f"滑动条是否可点击 {seek_bar_ele.get_attribute('clickable')}")
# 查看【滑动条】的属性
print(f"滑动条的 resource-id 属性为 {seek_bar_ele.get_attribute('resource-id')}")
print(f"滑动条的 text 属性为 {seek_bar_ele.get_attribute('text')}")
print(f"滑动条的 class 属性为 {seek_bar_ele.get_attribute('class')}")
print(f"滑动条的 content-desc 属性为 {seek_bar_ele.get_attribute('content-desc')}")
# 获取【滑动条】长度
seek_bar_ele_width = seek_bar_ele.size.get('width')
print(f"滑动条长度为 {seek_bar_ele_width}")
# 获取【滑动条】起始位置坐标
seek_bar_ele_start = seek_bar_ele.location
print(f"滑动条起始位置坐标为 {seek_bar_ele_start}")
# 获取【滑动条】中间位置坐标
seek_bar_center_x = seek_bar_ele_start.get("x") + seek_bar_ele_width / 2
seek_bar_center_y = seek_bar_ele_start.get("y")
seek_bar_center = (seek_bar_center_x, seek_bar_center_y)
print(f"滑动条中间位置坐标为 {seek_bar_center}")
# 点击【滑动条】中间位置
self.driver.tap([seek_bar_center], 1000)