Appium Python PO模式实践指南
项目结构
project/ ├── config/ # 配置文件 │ └── device_config.py # 设备配置参数 ├── pages/ # 页面对象模型(Page Object) │ └── home_page.py # 首页操作封装 ├── tests/ # 测试用例 │ └── test_ui_actions.py # UI 操作测试 ├── utils/ # 工具类 │ ├── driver.py # 驱动管理 │ └── adb_utils.py # ADB 命令封装(如关机、重启) └── conftest.py # pytest 全局配置
1. 配置文件 config/device_config.py
# Android 设备配置
ANDROID_CAPS = {
"platformName": "Android",
"appium:deviceName": "Pixel_4_API_30", # 设备名称(adb devices 查看)
"appium:platformVersion": "11.0", # 系统版本
"appium:appPackage": "com.android.settings", # 测试的 App 包名(示例为系统设置)
"appium:appActivity": ".Settings", # App 的主 Activity
"appium:automationName": "UiAutomator2", # Android 驱动引擎
"appium:noReset": True, # 不重置 App 状态
"appium:udid": "emulator-5554" # 设备唯一标识
}
APPIUM_SERVER = "http://localhost:4723/wd/hub" # Appium 服务地址
2. 驱动管理 utils/driver.py
from appium import webdriver
from config.device_config import APPIUM_SERVER, ANDROID_CAPS
def init_driver():
"""初始化 Appium 驱动"""
driver = webdriver.Remote(
command_executor=APPIUM_SERVER,
desired_capabilities=ANDROID_CAPS
)
return driver
def quit_driver(driver):
"""关闭驱动"""
if driver:
driver.quit()
3. 页面操作封装 pages/home_page.py
from appium.webdriver.common.appiumby import AppiumBy
class HomePage:
def __init__(self, driver):
self.driver = driver
# ------------------- 点击操作 -------------------
def click_element_by_id(self, element_id):
"""通过 ID 点击元素"""
self.driver.find_element(AppiumBy.ID, element_id).click()
def click_element_by_text(self, text):
"""通过文本点击元素(XPath 定位)"""
xpath = f"//*[@text='{text}']"
self.driver.find_element(AppiumBy.XPATH, xpath).click()
# ------------------- 滑动操作 -------------------
def swipe_up(self, duration=1000):
"""向上滑动屏幕"""
window_size = self.driver.get_window_size()
start_x = window_size["width"] * 0.5
start_y = window_size["height"] * 0.8
end_y = window_size["height"] * 0.2
self.driver.swipe(start_x, start_y, start_x, end_y, duration)
def swipe_to_element(self, element_id, max_swipes=5):
"""滑动直到找到元素"""
for _ in range(max_swipes):
try:
element = self.driver.find_element(AppiumBy.ID, element_id)
return element
except:
self.swipe_up()
raise Exception(f"Element {element_id} not found after {max_swipes} swipes")
# ------------------- 输入操作 -------------------
def input_text(self, element_id, text):
"""向输入框输入文本"""
element = self.driver.find_element(AppiumBy.ID, element_id)
element.clear()
element.send_keys(text)
4. 设备操作工具 utils/adb_utils.py
import subprocess
class ADBUtils:
def __init__(self, device_id="emulator-5554"):
self.device_id = device_id
def execute_adb_command(self, command):
"""执行 ADB 命令"""
cmd = f"adb -s {self.device_id} {command}"
subprocess.run(cmd, shell=True, check=True)
def reboot_device(self):
"""重启设备"""
self.execute_adb_command("reboot")
def power_off(self):
"""关闭设备(需 root 权限)"""
self.execute_adb_command("shell reboot -p")
def unlock_screen(self):
"""解锁屏幕"""
self.execute_adb_command("shell input keyevent 82") # KEYCODE_MENU
5. 测试用例 tests/test_ui_actions.py
import pytest
from utils.driver import init_driver, quit_driver
from pages.home_page import HomePage
from utils.adb_utils import ADBUtils
@pytest.fixture(scope="function")
def driver():
driver = init_driver()
yield driver
quit_driver(driver)
def test_click_and_swipe(driver):
home_page = HomePage(driver)
# 点击进入“网络和互联网”设置
home_page.click_element_by_text("网络和互联网")
# 滑动查找“热点”选项
home_page.swipe_to_element("com.android.settings:id/title")
def test_input_text(driver):
home_page = HomePage(driver)
# 进入“系统”设置
home_page.click_element_by_text("系统")
# 进入“关于手机”
home_page.click_element_by_text("关于手机")
# 输入设备名称
home_page.input_text("com.android.settings:id/device_name", "My Phone")
def test_reboot_device(driver):
adb = ADBUtils()
adb.reboot_device()
# 等待设备重启后重新连接
driver = init_driver()
assert driver.is_app_installed("com.android.settings")
6. 全局配置 conftest.py
import pytest
from utils.driver import init_driver, quit_driver
@pytest.fixture(scope="session", autouse=True)
def appium_server():
"""启动 Appium 服务(可选,或手动启动)"""
# 这里可以添加启动 Appium 的代码,但通常建议手动启动
yield
# 清理操作
关键操作详解
1. 点击操作
通过 ID 点击:直接使用 find_element(AppiumBy.ID, "element_id").click()
通过文本点击:使用 XPath 定位,如 //*[@text='确定']
2. 滑动操作
坐标滑动:driver.swipe(start_x, start_y, end_x, end_y, duration)
滑动到元素:结合循环和 swipe,直到找到目标元素。
3. 设备控制
重启/关机:通过 adb 命令实现(需设备权限)。
解锁屏幕:发送 ADB 按键事件(如 input keyevent 82)。
4. 输入文本
先清空输入框:element.clear()
输入内容:element.send_keys("text")
运行测试
# 启动 Appium 服务 appium # 运行测试 pytest tests/test_ui_actions.py -v
最佳实践
-
使用 Page Object 模式:将页面元素和操作封装到
pages目录。 -
分离配置和代码:设备参数放在
config中,便于多环境切换。 -
ADB 与 Appium 结合:复杂设备操作(如重启)用 ADB,UI 操作用 Appium。
-
异常处理:在滑动、查找元素时添加重试机制。
作者:白白胖胖充满希望丶