Appium是一个跨平台移动端自动化测试工具,能够很是便捷地为iOS和Android平台建立自动化测试用例。它能够模拟App内部的各类操做,如点击、滑动、文本输入等,只要咱们手工操做的动做Appium均可以完成。在前面咱们了解过Selenium,它是一个网页端的自动化测试工具。Appium实际上继承了Selenium,Appium也是利用WebDriver来实现App的自动化测试。对iOS设备来讲,Appium使用UIAutomation来实现驱动。对于Android来讲,它使用UiAutomator和Selendroid来实现驱动。python
Appium至关于一个服务器,咱们能够向Appium发送一些操做指令,Appium就会根据不一样的指令对移动设备进行驱动,完成不一样的动做。android
对于爬虫来讲,咱们用Selenium来抓取JavaScript渲染的页面,可见便可爬。Appium一样也能够,用Appium来作App爬虫不失为一个好的选择。ios
下面咱们来了解Appium的基本使用方法。git
咱们以Android平台的微信为例来演示Appium启动和操做App的方法,主要目的是了解利用Appium进行自动化测试的流程以及相关API的用法。github
请确保PC已经安装好Appium、Android开发环境和Python版本的Appium API。另外,Android手机安装好微信App。web
Appium启动App的方式有两种:一种是用Appium内置的驱动器来打开App,另外一种是利用Python程序实现此操做。下面咱们分别进行说明。服务器
首先打开Appium,启动界面以下图所示。微信
直接点击Start Server按钮便可启动Appium的服务,至关于开启了一个Appium服务器。咱们能够经过Appium内置的驱动或Python代码向Appium的服务器发送一系列操做指令,Appium就会根据不一样的指令对移动设备进行驱动,完成不一样的动做。启动后运行界面以下图所示。网络
Appium运行以后正在监听4723端口。咱们能够向此端口对应的服务接口发送操做指令,此页面就会显示这个过程的操做日志。app
将Android手机经过数据线和运行Appium的PC相连,同时打开USB调试功能,确保PC能够链接到手机。
能够输入adb命令来测试链接状况,以下所示:
adb devices -l
若是出现相似以下结果,这就说明PC已经正确链接手机。
List of devices attached 2da42ac0 device usb:336592896X product:leo model:MI_NOTE_Pro device:leo
model是设备的名称,就是后文须要用到的deviceName变量。我使用的是小米Note顶配版,因此此处名称为MI_NOTE_Pro。
若是提示找不到adb命令,请检查Android开发环境和环境变量是否配置成功。若是能够成功调用** adb **命令但不显示设备信息,请检查手机和PC的链接状况。
接下来用Appium内置的驱动器打开App,点击Appium中的Start New Session按钮,以下图所示。
这时会出现一个配置页面,以下图所示。
须要配置启动App时的Desired Capabilities参数,它们分别是** platformName、deviceName、appPackage、appActivity **。
在当前配置页面的左下角也有配置参数的相关说明,连接是https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md。
咱们在Appium中加入上面4个配置,以下图所示。
点击保存按钮,保存下来,咱们之后能够继续使用这个配置。
点击右下角的Start Session按钮,便可启动Android手机上的微信App并进入到启动页面。同时PC上会弹出一个调试窗口,从这个窗口咱们能够预览当前手机页面,并能够查看页面的源码,以下图所示。
点击左栏中屏幕的某个元素,如选中登陆按钮,它就会高亮显示。这时中间栏就显示了当前选中的按钮对应的源代码,右栏则显示了该元素的基本信息,如元素的id、class、text等,以及能够执行的操做,如Tap、Send Keys、Clear,以下图所示。
点击中间栏最上方的第三个录制按钮,Appium会开始录制操做动做,这时咱们在窗口中操做App的行为都会被记录下来,Recorder处能够自动生成对应语言的代码。例如,咱们点击录制按钮,而后选中App中的登陆按钮,点击Tap操做,即模拟了按钮点击功能,这时手机和窗口的App都会跳转到登陆页面,同时中间栏会显示此动做对应的代码,以下图所示。
接下来选中左侧的手机号文本框,点击Send Keys,对话框就会弹出。输入手机号,点击Send Keys,便可完成文本的输入,以下图所示。
咱们能够在此页面点击不一样的动做按钮,便可实现对App的控制,同时Recorder部分也能够生成对应的Python代码。
下面咱们看看使用Python代码驱动App的方法。首先须要在代码中指定一个Appium Server,而这个Server在刚才打开Appium的时候就已经开启了,是在4723端口上运行的,配置以下所示:
server = 'http://localhost:4723/wd/hub'
用字典来配置Desired Capabilities参数,代码以下所示:
desired_caps = { 'platformName': 'Android', 'deviceName': 'MI_NOTE_Pro', 'appPackage': 'com.tencent.mm', 'appActivity': '.ui.LauncherUI' }
新建一个Session,这相似点击Appium内置驱动的Start Session按钮相同的功能,代码实现以下所示:
from appium import webdriver from selenium.webdriver.support.ui import WebDriverWait driver = webdriver.Remote(server, desired_caps)
配置完成后运行,就能够启动微信App了。可是如今仅仅是能够启动App,尚未作任何动做。
再用代码来模拟刚才演示的两个动做:一个是点击“登陆”按钮,一个是输入手机号。
看看刚才Appium内置驱动器内的Recorder录制生成的Python代码,自动生成的代码很是累赘,例如点击“登陆”按钮的代码以下所示:
el1 = driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.View/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.RelativeLayout/android.widget.Button[1]") el1.click()
这段代码的XPath选择器路径太长,选择方式没有那么科学,获取元素时也没有设置等待,极可能会有超时异常。因此咱们修改一下,将其修改成经过ID查找元素,设置延时等待,两次操做的代码改写以下所示:
wait = WebDriverWait(driver, 30) login = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/cjk'))) login.click() phone = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/h2'))) phone.set_text('18888888888')
综上所述,完整的代码以下所示:
from appium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC server = 'http://localhost:4723/wd/hub' desired_caps = { 'platformName': 'Android', 'deviceName': 'MI_NOTE_Pro', 'appPackage': 'com.tencent.mm', 'appActivity': '.ui.LauncherUI' } driver = webdriver.Remote(server, desired_caps) wait = WebDriverWait(driver, 30) login = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/cjk'))) login.click() phone = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/h2'))) phone.set_text('18888888888')
必定要从新链接手机,再运行此代码,这时便可观察到手机上首先弹出了微信欢迎页面,而后模拟点击登陆按钮、输入手机号,操做完成。这样咱们就成功使用Python代码实现了App的操做。
接下来看看使用代码如何操做App、总结相关API的用法。这里使用的Python库为AppiumPythonClient,其GitHub地址为https://github.com/appium/python-client,此库继承自Selenium,使用方法与Selenium有不少共同之处。
须要配置Desired Capabilities参数,完整的配置说明能够参考https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md。通常来讲,配置几个基本参数便可,以下所示:
from appium import webdriver server = 'http://localhost:4723/wd/hub' desired_caps = { 'platformName': 'Android', 'deviceName': 'MI_NOTE_Pro', 'appPackage': 'com.tencent.mm', 'appActivity': '.ui.LauncherUI' } driver = webdriver.Remote(server, desired_caps)
这里配置了启动微信App的Desired Capabilities,这样Appnium就会自动查找手机上的包名和入口类,而后将其启动。包名和入口类的名称能够在安装包中的AndroidManifest.xml文件获取。
若是要打开的App没有事先在手机上安装,咱们能够直接指定App参数为安装包所在路径,这样程序启动时就会自动向手机安装并启动App,以下所示:
from appium import webdriver server = 'http://localhost:4723/wd/hub' desired_caps = { 'platformName': 'Android', 'deviceName': 'MI_NOTE_Pro', 'app': './weixin.apk' } driver = webdriver.Remote(server, desired_caps)
程序启动的时候就会寻找PC当前路径下的APK安装包,而后将其安装到手机中并启动。
咱们可使用Selenium中通用的查找方法来实现元素的查找,以下所示:
el = driver.find_element_by_id('com.tencent.mm:id/cjk')
在Selenium中,其余查找元素的方法一样适用,在此再也不赘述。
在Android平台上,咱们还可使用UIAutomator来进行元素选择,以下所示:
el = self.driver.find_element_by_android_uiautomator('new UiSelector().description("Animation")') els = self.driver.find_elements_by_android_uiautomator('new UiSelector().clickable(true)')
在iOS平台上,咱们可使用UIAutomation来进行元素选择,以下所示:
el = self.driver.find_element_by_ios_uiautomation('.elements()[0]') els = self.driver.find_elements_by_ios_uiautomation('.elements()')
还可使用iOS Predicates来进行元素选择,以下所示:
el = self.driver.find_element_by_ios_predicate('wdName == "Buttons"') els = self.driver.find_elements_by_ios_predicate('wdValue == "SearchBar" AND isWDDivisible == 1')
也可使用iOS Class Chain来进行选择,以下所示:
el = self.driver.find_element_by_ios_class_chain('XCUIElementTypeWindow/XCUIElementTypeButton[3]') els = self.driver.find_elements_by_ios_class_chain('XCUIElementTypeWindow/XCUIElementTypeButton')
可是此种方法只适用于XCUITest驱动,具体能够参考:https://github.com/appium/appium-xcuitest-driver。
点击可使用tap()方法,该方法能够模拟手指点击(最多五个手指),可设置按时长短(毫秒),代码以下所示:
tap(self, positions, duration=None)
其中后两个参数以下。
driver.tap([(100, 20), (100, 60), (100, 100)], 500)
这样就能够模拟点击屏幕的某几个点。
对于某个元素如按钮来讲,咱们能够直接调用cilck()方法实现模拟点击,实例以下所示:
button = find_element_by_id('com.tencent.mm:id/btn') button.click()
可使用scroll()方法模拟屏幕滚动,用法以下所示:
scroll(self, origin_el, destination_el)
能够实现从元素origin_el滚动至元素destination_el。
它的后两个参数以下。
driver.scroll(el1,el2)
可使用swipe()模拟从A点滑动到B点,用法以下所示:
swipe(self, start_x, start_y, end_x, end_y, duration=None)
后面几个参数说明以下。
driver.swipe(100, 100, 100, 400, 5000)
这样能够实如今5s时间内,由(100, 100)滑动到 (100, 400)。
可使用**flick()**方法模拟从A点快速滑动到B点,用法以下所示:
flick(self, start_x, start_y, end_x, end_y)
几个参数说明以下。
driver.flick(100, 100, 100, 400)
可使用**drag_and_drop()**将某个元素拖动到另外一个目标元素上,用法以下所示:
drag_and_drop(self, origin_el, destination_el)
能够实现将元素origin_el拖曳至元素destination_el。
两个参数说明以下。
driver.drag_and_drop(el1, el2)
可使用**set_text()**方法实现文本输入,以下所示:
el = find_element_by_id('com.tencent.mm:id/cjk') el.set_text('Hello')
与Selenium中的ActionChains相似,Appium中的TouchAction可支持的方法有**tap()、press()、long_press()、release()、move_to()、wait()、cancel()**等,实例以下所示:
el = self.driver.find_element_by_accessibility_id('Animation') action = TouchAction(self.driver) action.tap(el).perform()
首先选中一个元素,而后利用TouchAction实现点击操做。
若是想要实现拖动操做,能够用以下方式:
els = self.driver.find_elements_by_class_name('listView') a1 = TouchAction() a1.press(els[0]).move_to(x=10, y=0).move_to(x=10, y=-75).move_to(x=10, y=-600).release() a2 = TouchAction() a2.press(els[1]).move_to(x=10, y=10).move_to(x=10, y=-300).move_to(x=10, y=-600).release()
利用以上API,咱们就能够完成绝大部分操做。更多的API操做能够参考:https://testerhome.com/topics/3711。
本文文章转载,摘子于:
https://cloud.tencent.com/developer/article/1151796
做者:崔庆才
静觅博客博主,《Python3网络爬虫开发实战》做者