第三方软件测试机构:Appium如何使用Selenium的客户端库?
第三方软件测试机构:Appium 通过遵循 W3C WebDriver 协议,实现了与 Selenium 客户端库的无缝兼容。
下面解释其原理、配置方法和具体实现方法。
为什么可以共用?
统一的 WebDriver 协议:
Selenium 和 Appium 都遵循 W3C WebDriver 标准协议。这是一个基于 HTTP 的 RESTful API 规范。
Selenium Client Library(Java, Python, C# 等版本)的本质是一个 HTTP 客户端,它负责将你的自动化指令(如 find_element, click)封装成符合 WebDriver 协议的 HTTP 请求。
Selenium Server(或浏览器驱动)和 Appium Server 都是 HTTP 服务器,它们接收这些请求,并将其翻译成对特定目标(浏览器/移动设备)的实际操作。
架构对比:
Selenium 流程: Selenium客户端代码 -> (HTTP请求) -> Selenium Server / 浏览器驱动 -> (操作) -> 浏览器
Appium 流程: Selenium客户端代码 -> (HTTP请求) -> Appium Server -> (通过移动设备驱动) -> 移动设备/模拟器
由于客户端发送的请求格式是标准的,你只需要将请求的目标从 Selenium Server 换成 Appium Server 即可。这就是为什么你可以使用完全相同的 Selenium 客户端库来编写 Appium 脚本。
配置:从 Selenium 到 Appium 的切换
从 Selenium 切换到 Appium,唯一需要改变的是 Remote WebDriver 的初始化配置。你需要指定两个要素:
Appium Server 的地址: 代替原来的 Selenium Server 或直接浏览器驱动地址。
Desired Capabilities: 这是一组键值对,用于告诉 Appium Server 你要测试什么样的设备或应用。这是与 Selenium 最大的不同之处。
具体实现:代码示例
以下通过对比 Selenium 和 Appium 的代码来展示如何复用客户端库。
1. Python 示例
Selenium (测试 Chrome 浏览器):
python
from selenium import webdriver
from selenium.webdriver.common.by import By# 初始化本地Chrome驱动
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
# 或者使用 Selenium Grid
# driver = webdriver.Remote(
# command_executor='http://your-selenium-grid-hub:4444/wd/hub',
# desired_capabilities={'browserName': 'chrome'}
# )driver.get("https://www.baidu.com")
search_box = driver.find_element(By.ID, "kw")
search_box.send_keys("Selenium")
driver.quit()
Appium (测试 Android App):
python
from appium import webdriver # 注意:这里依然是从 `appium` 包导入 `webdriver`,但它底层是扩展了Selenium的WebDriver。
from selenium.webdriver.common.by import By
import desired_capabilities# Appium 特定的 Desired Capabilities
desired_caps = {'platformName': 'Android', # 平台:Android 或 iOS'platformVersion': '11', # 安卓系统版本'deviceName': 'Android Emulator', # 设备名称,模拟器或真机名'automationName': 'UiAutomator2', # 自动化引擎,Android推荐UiAutomator2'app': '/path/to/your/app.apk', # 安装的App路径,也可以是应用包名# 'appPackage': 'com.example.app', # 已安装应用的包名# 'appActivity': '.MainActivity', # 要启动的Activity名
}# 关键区别:初始化 Remote WebDriver,连接到 Appium Server
# 假设Appium Server运行在本机默认端口4723
driver = webdriver.Remote(command_executor='http://localhost:4723/wd/hub',desired_capabilities=desired_caps
)# !!!从这里开始,你可以使用完全相同的 Selenium WebDriver API !!!
el = driver.find_element(By.ID, "com.example.app:id/button")
el.click()
driver.find_element(By.CLASS_NAME, "android.widget.EditText").send_keys("Hello Appium!")driver.quit()
2. Java 示例
Selenium (测试 Chrome 浏览器):
java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;public class SeleniumTest {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");WebDriver driver = new ChromeDriver();driver.get("https://www.baidu.com");driver.findElement(By.id("kw")).sendKeys("Selenium");driver.quit();}
}
Appium (测试 Android App):
java
import io.appium.java_client.android.AndroidDriver; // Appium 提供的特定Driver,扩展了Selenium的RemoteWebDriver
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.By;
import java.net.URL;public class AppiumTest {public static void main(String[] args) throws Exception {DesiredCapabilities desiredCaps = new DesiredCapabilities();desiredCaps.setCapability("platformName", "Android");desiredCaps.setCapability("platformVersion", "11");desiredCaps.setCapability("deviceName", "Android Emulator");desiredCaps.setCapability("automationName", "UiAutomator2");desiredCaps.setCapability("app", "/path/to/your/app.apk");// 关键区别:初始化 AndroidDriver(它是 RemoteWebDriver 的子类),连接到 Appium ServerAndroidDriver driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"),desiredCaps);// !!!从这里开始,你可以使用完全相同的 WebDriver API !!!driver.findElement(By.id("com.example.app:id/button")).click();driver.findElement(By.className("android.widget.EditText")).sendKeys("Hello Appium!");driver.quit();}
}
说明
appium 客户端库是封装器:
在 Python 中,你安装的 appium-python-client 库,其 webdriver 模块是对 Selenium webdriver 的扩展。它添加了移动端特有的功能,但核心 API 完全兼容。
在 Java 中,io.appium.java_client 包下的 AndroidDriver 和 IOSDriver 是 RemoteWebDriver 的子类,同样兼容所有父类方法。
Desired Capabilities :
这是 Selenium 和 Appium 配置上最大的区别。你需要花时间熟悉各种 Capability,如 appPackage, appActivity, noReset, fullReset 等,它们控制着 Appium 的行为。
定位的异同:
通用: ID, CLASS_NAME, XPATH 在 Appium 中同样有效。但 ID 在 Android 中对应的是 resource-id,在 iOS 中对应的是 accessibility id。
移动端特有方法:
accessibility id: 跨平台的理想选择,对应元素的 content-desc (Android) 或 accessibility identifier (iOS)。
-image: 通过图像识别定位(较慢,不推荐为首选)。
-uiautomator / -predicate: 平台原生的强大定位方式。
移动端操作:
虽然核心 API 相同,但 Appium 客户端库扩展了更多移动端特有的方法,这些方法在纯 Selenium 中是没有的。例如:
python
# Python 示例
driver.start_activity('com.package.name', 'ActivityName') # 启动特定Activity
driver.get_clipboard_text() # 获取剪贴板内容
driver.swipe(start_x, start_y, end_x, end_y, duration) # 滑动
# Java 示例
((AndroidDriver) driver).startActivity(new Activity("com.package.name", "ActivityName"));
((CanGetClipboardText) driver).getClipboardText();
这些扩展方法使得对移动设备的控制更加精细和强大。
总结
Appium 完全构建在 Selenium 的生态系统之上。 你使用 Selenium 的客户端库来编写脚本,只需要:
改变连接目标:从 localhost:port(浏览器驱动)或 Grid Hub 改为 localhost:4723(Appium Server)。
配置移动端参数:使用 Desired Capabilities 来指定设备、应用和自动化引擎。
利用扩展功能:使用 Appium 客户端库提供的移动端特有方法来增强脚本能力。
这种设计极大地降低了学习成本,如果你熟悉 Selenium,那么上手 Appium 会非常快。