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。
-
异常处理:在滑动、查找元素时添加重试机制。
作者:白白胖胖充满希望丶