Appium 基础操作 API

启动代码(前置代码)

# 导模块 
from appium import webdriver 

# 创建一个字典,包装相应的启动参数 
desired_caps = dict() 
# 需要连接的手机的平台(不限制大小写) 
desired_caps['platformName'] = 'Android' 
# 需要连接的手机的版本号(比如 9.2.1 的版可以填写9.2.1或9.2或9,以此类推)
desired_caps['platformVersion'] = '9' 
# 需要连接的手机的设备号(andoird平台下,可以随便写,但是不能不写) 
desired_caps['deviceName'] = '192.168.56.101:5555' 
# 需要启动的程序的包名 
desired_caps['appPackage'] = '启动的包名' 
# 需要启动的程序的界面名 
desired_caps['appActivity'] = '启动的界面名'
# 文本框输入中文时要用
desired_caps['unicodeKeyboard'] = True 
desired_caps['resetKeyboard'] = True

# 连接appium服务器,获取driver
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) 

# 退出driver
driver.quit()

启动过程:

注:appium的启动实际上是在本机使用了4723端口开启了一个服务

  1. python 代码会访问本机的 appium 服务器,并获取 driver 对象
  2. appium 会将我们的 driver 对象调用的方法转化成 post 请求,提交给appium服务器
  3. appium 通过接收到的 post 请求发送给手机,再由手机进行执行 

1、在脚本内启动其他 app

应用场景:如果一个应用需要跳转到另外一个应用,就可以使用这个 api 进行应用的跳转,就像我们通过外卖应用下订单之后会跳转到支付应用一样

方法:

# 参数: 
    # appPackage:要打开的程序的包名 
    # appActivity:要打开的程序的界面名 
driver.start_activity(appPackage, appActivity)

2、获取 app 的包名和界面名

应用场景:当我们从一个应用跳转到另外一个应用的时候,想输出其包名、界面名或者想在报告中展现对应信息, 我们就可以调用这个属性来进行获取

方法:

# 获取包名 
driver.current_package 

# 获取界面名 
driver.current_activity

3、关闭 app 和驱动对象

应用场景:有的时候我们需要关闭某个应用程序后,再打开新的应用

方法:

# 关闭当前操作的app,不会关闭驱动对象 
driver.close_app() 

# 关闭驱动对象,同时关闭所有关联的app 
driver.quit()

4、安装和卸载以及是否安装app

应用场景:一些应用市场的软件可能会有一个按钮,如果某一个程序已经安装则卸载,如果没有安装则安装

方法:

# 安装app 
# 参数: 
    # app_path:apk路径 
driver.install_app(app_path)

# 卸载app 
# 参数: 
    # app_id:应用程序包名 
driver.remove_app(app_id)

# 判断app是否已经安装 
# 参数: 
    # app_id:应用程序包名 
# 返回值: 
    # 布尔类型,True为安装,False为没有安装 
driver.is_app_installed(app_id)

5、将应用置于后台

应用场景:银行类 app 会在进入后台一定时间后,如果再回到前台也页面会重新输入密码,如果需要自动化测试这种功能,可以使用这个 api 进行测试

方法:

# app放置到后台一定时间后再回到前台,模拟热启动 
# 参数: 
    # seconds:后台停留多少秒 
driver.background_app(seconds)

热启动:表示进入后台回到前台。关机再开这种切断电源的行为可以叫做“冷启动”

6、元素定位

应用场景:需要通过元素定位来获取元素,才能让计算机帮我们 ”操作“ 这个元素

元素属性值获取:通过安装的Android SDK目录下的uiautomatorviewer工具可以获取

定位一个元素方法:

  • 通过id定位一个元素
# 参数: 
    # id_value:元素的resource-id属性值 
# 返回值: 
    # 定位到的单个元素 
driver.find_element_by_id(id_value)
  • 通过class_name定位一个元素
# 参数: 
    # class_value:元素的class属性值 
# 返回值: 
    # 定位到的单个元素 
driver.find_element_by_class_name(class_value)
  • 通过xpath定位一个元素
# 参数: 
    # xpath_value:定位元素的xpath表达式 
# 返回值: 
    # 定位到的单个元素 
driver.find_element_by_xpath(xpath_value)

定位一组元素方法:

  •  通过id定位一组元素
# 参数: 
    # id_value:元素的resource-id属性值 
# 返回值: 
    # 列表,定位到的所有符合调价你的元素 
driver.find_elements_by_id(id_value)
  • 通过class_name定位一组元素
# 参数: 
    # class_value:元素的class属性值 
# 返回值: 
    # 列表,定位到的所有符合调价你的元素 
driver.find_elements_by_class_name(class_value)
  • 通过xpath定位一组元素
# 参数: 
    # xpath_value:定位元素的xpath表达式 
# 返回值: 
    # 列表,定位到的所有符合调价你的元素 
driver.find_elements_by_xpath(xpath_value)

注意点:

1、元素的定位基于当前屏幕范围内展示的可见元素。

2、如果使用 find_element_by_xx 方法,如果传入一个没有的特征,会报NoSuchElementException 的错误。

3、如果使用 find_elements_by_xx 方法,如果传入一个没有的特征,不会报错,会返回一个空列表。

7、元素等待

应用场景:可能由于一些网络速度原因、服务器处理请求、电脑配置原因等等,我们想找的元素并没有立刻出来,此时如果直接定位可能会报错

分类:隐式等待和显示等待

(1)隐式等待

作用范围:针对所有定位元素的操作(全局有效)

方法:

# 参数: 
    # timeout:超时的时长,单位:秒 
implicitly_wait(timeout)

(2)显示等待

作用范围:针对某一个定位元素的操作(单个有效)

方法:

# 导入显示等待包
from selenium.webdriver.support.wait import WebDriverWait


# 参数: 
    # driver:驱动对象 
    # timeout:超时的时长,单位:秒 
    # poll_frequency:检测间隔时间,默认为0.5秒
    # method:lambda查找元素表达式
# 返回值: 
    # 定位到的元素,如果没有定位到会抛出TimeoutException异常 
element = WebDriverWait(driver, timeout, poll_frequency=0.5).until(method)

8、点击元素

应用场景:需要点击某个按钮的时候使用

方法:

# 对element按钮进行点击操作
element.click()

9、输入和清空输入框内容

应用场景:需要对输入框进行输入或清空的时候使用

方法:

# 对element输入框进行输入操作 
# 参数: 
    # value:输入的内容 
element.send_keys(value) 

# 对element输入框进行输入操作 
element.clear()

注意点: 默认输入中文无效,但不会报错,需要在 ”前置代码“ 中有着这两个参数

desired_caps['unicodeKeyboard'] = True 
desired_caps['resetKeyboard'] = True

10、获取元素的文本内容

应用场景:需要获取按钮、文本框、输入框等控件的文本内容时使用

方法:

# 获取element控件的文本内容 
# 返回值: 
    # 控件的文本内容 
element.text

11、获取元素的位置和大小

应用场景:需要获取元素的位置和大小的时候使用

方法:

# 获取element的位置 
# 返回值: 
    # 字典,x为元素的x坐标,y为元素的y坐标 
element.location 

# 获取element的大小 
# 返回值: 
    # 字典,width为宽度,height为告诉 
element.size

12、获取元素的属性值

应用场景:根据特征定位到元素后,使元素的属性名获取对应的属性值

方法:

# 获取element的属性值
# 参数: 
    # value:要获取的属性名 
# 返回值: 
    # 根据属性名得到的属性值 
element.get_attribute(value)     # value:元素的属性

注意点:

value='text' 返回text的属性值

value='name' 返回content-desc / text属性值

value='className' 返回 class属性值,只有 API=>18 才能支持

value='resourceId' 返回 resource-id属性值,只有 API=>18 才能支持

13、滑动和拖拽事件

应用场景:有些按钮是需要滑动几次屏幕后才会出现,此时我们需要使用代码来模拟手指的滑动

分类:swipe滑动事件、scroll滑动事件、drag_and_drop拖拽事件

(1)swipe滑动事件

概念:从一个坐标位置滑动到另一个坐标位置,只能是两个点之间的滑动(惯性根据时间变化)

方法:

# 参数: 
    # start_x: 起点X轴坐标 
    # start_y: 起点Y轴坐标 
    # end_x: 终点X轴坐标 
    # end_y: 终点Y轴坐标 
    # duration: 滑动这个操作一共持续的时间长度,单位:ms 
driver.swipe(start_x, start_y, end_x, end_y, duration=None)

距离相同时,持续时间越长,惯性越小

持续时间相同时,手指滑动的距离越大,实际滑动的距离也就越大

(2)scroll滑动事件

概念:从一个元素滑动到另一个元素,直到页面自动停止(惯性很大)

方法:

# 参数: 
    # origin_el: 滑动开始的元素 
    # destination_el: 滑动结束的元素 
driver.scroll(origin_el, destination_el)

(3)drag_and_drop拖拽事件

概念:从一个元素滑动到另一个元素,第二个元素替代第一个元素原本屏幕上的位置(无惯性)

方法:

# 参数: 
    # origin_el: 滑动开始的元素 
    # destination_el: 滑动结束的元素 
driver.drag_and_drop(origin_el, destination_el)

14、高级手势TouchAction

应用场景:TouchAction 可以实现一些针对手势的操作,比如滑动、长按、拖动等。我们可以将这些基本手势组合 成一个相对复杂的手势。比如,我们解锁手机或者一些应用软件都有手势解锁的这种方式。

使用步骤:

  • 1. 创建 TouchAction 对象
  • 2. 通过对象调用想执行的手势
  • 3. 通过 perform() 执行动作

(1)轻敲操作

概念:模拟手指对某个元素或坐标按下并快速抬起

方法:

# 参数: 
    # element:元素 
    # x:x坐标 
    # y:y坐标 
TouchAction(driver).tap(element=None, x=None, y=None).perform()

注:元素和坐标任选其一,选择坐标时需要标明x=,y=,否则会被误认为是element

(2)按下和抬起操作

概念:模拟手指一直按下,模拟手指抬起。可以用来组合成轻敲或长按的操作

方法:

# 模拟手指对元素或坐标的按下操作 
# 参数: 
    # el:元素 
    # x:x坐标 
    # y:y坐标 
TouchAction(driver).press(el=None, x=None, y=None).perform() 

# 模拟手指对元素或坐标的抬起操作 
TouchAction(driver).release().perform()

(3)等待操作

概念:模拟手指等待,比如按下后等待 5 秒之后再抬起

方法:

# 参数: 
    # ms:暂停的毫秒数 
TouchAction(driver).wait(ms=0).perform()

(4)长按操作

概念:模拟手指对元素或坐标的长按操作。比如,长按某个按钮弹出菜单

方法:

# 参数: 
    # el:元素 
    # x:x坐标 
    # y:y坐标 
    # duration:长按时间,毫秒 
TouchAction(driver).long_press(el=None, x=None, y=None, duration=1000).perform()

(5)移动操作

概念:模拟手指移动操作,比如,手势解锁需要先按下,再移动

方法:

# 参数: 
    # el:元素 
    # x:x坐标 
    # y:y坐标 
TouchAction(driver).move_to(el=None, x=None, y=None).perform()

15、获取手机分辨率

应用场景:需要根据当前设备的屏幕分辨率来计算一些点击或者滑动的坐标

方法:

driver.get_window_size()    # 返回值是字典{'height'= x, 'width'= x}

16、获取手机截图

应用场景:有些自动化的操作可能没有反应,但并不报错。此时我们就可以将操作过后的关键情况,截图留存。后期也可以根据图片发现问题

方法:

# 参数: 
    # filename:指定路径下,指定格式的图片 
get_screenshot_as_file(filename)

17、获取和设置手机网络

应用场景:视频应用在使用流量看视频的时候,大部分都会提示用户正在是否继续播放。我们可能需要用自动化的形式来判断是否有对应的提示。即用流量的时候应该有提示,不用流量的时候应该没有提示。

方法:

# 获取手机网络 
driver.network_connection

# 设置手机网络 
    # 参数: # connectionType:网络类型 
driver.set_network_connection(connectionType)

手机网络类型对照: (流量、WiFi、飞行模式)

18、发送键到设备

应用场景:模拟按 “返回键” “home键” “音量加减”等等操作

方法:

# 参数: 
    # keycode:发送给设备的关键代码 
    # metastate:关于被发送的关键代码的元信息,一般为默认值 
driver.press_keycode(keycode, metastate=None)

常用的手机键:

键名 键名 关键代码
KEYCODE_HOME 按键Home 3
KEYCODE_MENU 菜单键 82
KEYCODE_BACK 返回键 4
KEYCODE_VOLUME_UP 音量增加键 24
KEYCODE_VOLUME_DOWN 音量减少键 25

按键对应的编码,可以搜索关键字 “android keycode”

例如:https://blog.csdn.net/feizhixuan46789/article/details/16801429

19、打开和关闭手机通知栏

应用场景:想通过通知栏来判断手机是否收到消息,一定要先操作手机的通知栏

方法:

# 打开手机通知栏 
driver.open_notifications()

# 关闭手机通知栏
driver.press_keycode(4)    # 直接返回就能关闭,没有专门的方法关闭

猜你喜欢

转载自blog.csdn.net/ouihsiad/article/details/127240442