
你的测试脚本
↓(WebDriver 协议)
Appium Server
↓(翻译为平台原生命令)
├── iOS:XCUITest(Apple 官方测试框架)
└── Android:UiAutomator2 / Espresso(Google 官方测试框架)
# 1. 安装 JDK 17
# 2. 安装 Android SDK(通过 Android Studio)
# 3. 安装 Appium Doctor 检查环境
npm install -g appium-doctor
appium-doctor --android
# 1. 安装 Xcode
# 2. 安装 XCUITest 驱动
appium driver install xcuitest
# 3. 检查环境
appium-doctor --ios
npm install -g appium
appium driver install uiautomator2 # Android 驱动
appium driver install xcuitest # iOS 驱动
appium server # 启动服务
pip install Appium-Python-Client
from appium import webdriver
# Android 配置
android_caps = {
"platformName": "Android",
"appium:deviceName": "Pixel 7",
"appium:platformVersion": "14",
"appium:automationName": "UiAutomator2",
"appium:app": "/path/to/app.apk"
}
# iOS 配置(Mac 上运行)
ios_caps = {
"platformName": "iOS",
"appium:deviceName": "iPhone 15",
"appium:platformVersion": "17.0",
"appium:automationName": "XCUITest",
"appium:app": "/path/to/app.ipa"
}
# 切换平台只需要改配置
driver = webdriver.Remote("http://127.0.0.1:4723", android_caps)
from appium.webdriver.common.appiumby import AppiumBy
# 1. Accessibility ID(跨平台推荐)
element = driver.find_element(AppiumBy.ACCESSIBILITY_ID, "login_button")
# 2. Android 专用:resource-id
element = driver.find_element(AppiumBy.ID, "com.example.app:id/username")
# 3. XPath(跨平台,但慢)
element = driver.find_element(AppiumBy.XPATH, '//android.widget.EditText[@text="用户名"]')
# 4. iOS 专用:Predicate
element = driver.find_element(AppiumBy.IOS_PREDICATE, "label == '登录' AND type == 'XCUIElementTypeButton'")
# 5. iOS 专用:Class Chain
element = driver.find_element(AppiumBy.IOS_CLASS_CHAIN, "**/XCUIElementTypeButton[`label == '登录'`]")
# base_page.py - 跨平台基类
class BasePage:
def __init__(self, driver):
self.driver = driver
def find(self, locator):
return self.driver.find_element(*locator)
def click(self, locator):
self.find(locator).click()
def type_text(self, locator, text):
self.find(locator).clear()
self.find(locator).send_keys(text)
# login_page.py - 登录页(平台差异在这里处理)
class LoginPage(BasePage):
# Android 定位器
ANDROID = {
"username": (AppiumBy.ID, "com.example.app:id/username"),
"password": (AppiumBy.ID, "com.example.app:id/password"),
"login_btn": (AppiumBy.ID, "com.example.app:id/login"),
}
# iOS 定位器
IOS = {
"username": (AppiumBy.ACCESSIBILITY_ID, "username_field"),
"password": (AppiumBy.ACCESSIBILITY_ID, "password_field"),
"login_btn": (AppiumBy.ACCESSIBILITY_ID, "login_button"),
}
def __init__(self, driver, platform):
super().__init__(driver)
self.locators = self.ANDROID if platform == "android" else self.IOS
def login(self, username, password):
self.type_text(self.locators["username"], username)
self.type_text(self.locators["password"], password)
self.click(self.locators["login_btn"])
import pytest
@pytest.fixture(params=["android", "ios"])
def login_page(request):
platform = request.param
caps = ANDROID_CAPS if platform == "android" else IOS_CAPS
driver = webdriver.Remote(SERVER_URL, caps)
yield LoginPage(driver, platform)
driver.quit()
def test_login_success(login_page):
login_page.login("testuser", "password123")
# 验证登录成功(跨平台断言)
assert is_logged_in(login_page.driver)
# Appium 2.0 Inspector
appium inspector
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((AppiumBy.ACCESSIBILITY_ID, "submit"))
)
# Android
adb devices
# iOS
xcrun xctrace list devices
input_field.click() # 先点击获取焦点
input_field.send_keys("文本")
# 获取所有上下文
contexts = driver.contexts
# 切换到 WebView
driver.switch_to.context("WEBVIEW_com.example.app")
# 切回原生
driver.switch_to.context("NATIVE_APP")
from appium.webdriver.common.touch_action import TouchAction
# 向上滑动
TouchAction(driver).press(x=500, y=1500).move_to(x=500, y=500).release().perform()
# 长按
TouchAction(driver).long_press(element).release().perform()
相关推荐