Appium的简要说明
Appium是一个开源的自动化测试工具,其支持iOS和安卓平台上的原生的,基于移动浏览器的,混合的应用。
Appium 理念
Appium是基于以下的四个理念设计来满足移动平台测试自动化的要求的:
您不应该因为需要自动化测试您的应用而不得不以任何形式去重新编译或者修改你的app
您不应该把自己固定在一门特定的语言和一个特定的框架上去实现和运行你的测试
当说到测试自动化APIs的时候,一个移动测试框架不应该做“重新发明轮子”的事情,
一个移动测试自动化框架应该是开源的,无论是在精神上,实际上,还是名义上!
使用Appium进行自动化测试有两个好处
Appium在不同平台中使用了标准的自动化APIs,所以在跨平台时,不需要重新编译或者修改自己的应用。
Appium支持Selenium WebDriver支持的所有语言,如java、Object-C、JavaScript、Php、Python、Ruby、C#、Clojure,或者Perl语言,更可以使用Selenium WebDriver的Api。Appium支持任何一种测试框架.Appium实现了真正的跨平台自动化测试。(本文主要介绍Python的用法)
Appium架构
Appium 是一个用Node.js编写的HTTP server,它创建、并管理多个 WebDriver sessions 来和不同平台交互,如 iOS ,Android等等.
Appium 开始一个测试后,就会在被测设备(手机)上启动一个 server ,监听来自 Appium server的指令. 每种平台像 iOS 和Android都有不同的运行、和交互方式。所以Appium会用某个桩程序“侵入”该平台,并接受指令,来完成测试用例的运行。
安装
appium下载地址:Appium: Mobile App Automation Made Awesome.
python安装库
pip install Appium-Python-Client
前置条件
搭建java环境,这里不再赘述
搭建Android环境,sdk下载地址:http://developer.android.com/sdk/index.html,国内的sdk tools下载地址:http://www.androiddevtools.cn/
安装node.js:https://nodejs.org/en/
下载并安装完毕后,打开appium,点击Edit Configurations按钮,设置安卓根目录和java根目录。
初始化
首先在本机开启appium服务器,ip不变,端口号为4723
引入appium
from appium import webdriver
输入启动参数,这里只是连接对应的安卓手机
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['deviceName'] = 'UUID'
具体的参数,地址:【appium】appium自动化入门之基本参数完整版(67个appium基本参数和关键字)Chaqian的博客-CSDN博客appium参数
开启appium的session连接
driver = webdriver.Remote("http://localhost:4723/wd/hub",desired_caps)
注意:http://localhost:4723/wd/hub
这里的wd/hub
不能多/
,否则报错
测试连接,开启淘宝app
driver.activate_app("com.taobao.taobao")
apk操作
打开app
# 打开淘宝
driver.activate_app("com.taobao.taobao")
查看打开的app的包名有3种办法
第一种
cmd中输入命令:adb bash am monitor
然后启动需要获取包名的应用
第二种
cmd中输入命令:adb bash pm list packages -3
查看自己安装的app包名
第三种
下载雷电模拟器的包名类名查看器,找到app后直接点击复制包名(方便快捷)
下载地址:包名类名查看器电脑版下载包名类名查看器PC版下载雷电安卓模拟器 (ldmnq.com)
停止应用运行
以网易云音乐为例
stop_app("com.netease.cloudmusic")
安装/卸载应用
# 安装应用
driver.install_app("D:\demo\tutorial-blackjack-release-signed.apk")
# 卸载应用
driver.remove_app("com.netease.cloudmusic")
元素获取
首先引入AppiumBy
from selenium.webdriver.common.by import By
这里用find_element
接口,通过by
和value
寻找数值
driver.find_element(by=By.XPATH,value = "//android.widget.FrameLayout[@content-desc=\"消息\"]/android.widget.ImageView")
by
的参数,可以通过AppiumBy
去获取,常用的分别有:
By.XPATH
By.NAME
By.ID
By.CLASS_NAME
By.LINK_TEXT
模拟操作
首先引入TouchAction
from appium.webdriver.common.touch_action import TouchAction
普通的点击
driver.find_element(by=AppiumBy.XPATH,value = "//android.widget.FrameLayout[@content-desc=\"消息\"]/android.widget.ImageView").click()
手指轻敲屏幕操作
# 通过元素定位方式敲击屏幕
el = driver.find_element(by=AppiumBy.XPATH,value = "//*[contains(@text,'WLAN')]")
TouchAction(driver).tap(el).perform()
#perform()方法发送命令到服务器执行操作
# 通过坐标方式敲击屏幕,元素坐标:x=149,y=324
TouchAction(driver).tap(x=149,y=324).perform()
手指按下和释放操作
# 通过元素定位方式按下屏幕
el = driver.find_element(by=AppiumBy.XPATH,value = "//*[contains(@text,'WLAN')]")
TouchAction(driver).press(el).release().perform()
#通过坐标的方式,元素坐标x=149,y=324
TouchAction(driver).press(147,324).release().perform()
手指长按操作
el =driver.find_element_by_id("android:id/title")
# 通过元素定位方式长按元素
TouchAction(driver).long_press(el,duration=5000).release().perform()
# 通过坐标方式长按元素,WiredSSID坐标:x=770,y=667
# wait(5000)等待五秒
# 添加等待(有长按X效果)/不添加等待(无长按效果)
TouchAction(driver).long_press(x=770,y=667,duration=5000).release().perform()
滑动
driver.swipe(start_x,start_y,end_x,end_y)
元素等待
引入WebDriverWait
和expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
实例:
WebDriverWait(driver,timeout=10).until(EC.element_to_be_clickable(el),message="找到元素啦")
WebDriverWait
与until
、expected_conditions
联合判别元素是否存在,API如下:
title_is
: 判断当前页面的title是否精确等于预期title_contains
: 判断当前页面的title是否包含预期字符串presence_of_element_located
: 判断某个元素是否被加到了dom树里,并不代表该元素一定可见visibility_of_element_located
: 判断某个元素是否可见.可见代表元素非隐藏,并且元素的宽和高都不等于0visibility_of
: 跟上面的方法做一样的事情,只是上面的方法要传入locator,这个方法直接传定位到的element就好了presence_of_all_elements_located
: 判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是'column-md-3',那么只要有1个元素存在,这个方法就返回Truetext_to_be_present_in_element
: 判断某个元素中的text是否包含了预期的字符串text_to_be_present_in_element_value
: 判断某个元素中的value属性是否包含了预期的字符串frame_to_be_available_and_switch_to_it
: 判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回Falseinvisibility_of_element_located
: 判断某个元素中是否不存在于dom树或不可见element_to_be_clickable
: 判断某个元素中是否可见并且是enable的,这样的话才叫clickablestaleness_of
: 等某个元素从dom树中移除,注意,这个方法也是返回True或Falseelement_to_be_selected
: 判断某个元素是否被选中了,一般用在下拉列表element_selection_state_to_be
: 判断某个元素的选中状态是否符合预期element_located_selection_state_to_be
: 跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locatoralert_is_present
: 判断页面上是否存在alert