Android自动化常用操作

1、在脚本内启动其他程序

driver.start_activity(包名,界面名)

driver.start_activity('appPackage','appActivity')
2、将应用置于后台

进入后台3秒,然后再回到前台

driver.background_app(3)
3、关闭应用程序

关闭当前操作的应用程序,但不会关闭驱动对象

driver.close_app()

关闭驱动对象,同时,关闭所有关联的应用程序

driver.quit()
4、安装和卸载应用程序

安装应用程序

driver.install_app(path)

卸载应用程序

driver.remove_app(app_id)

判断是否安装应用程序,安装的话返回Ture,没有安装的话返回False

driver.is_app_installed(app_id)
5、获取元素的文本

text方法,返回文本

element.text
6、获取元素的位置和大小

location方法,返回键为x、y的字典

element.location

size方法,返回键为width,height的字典

element.size
7、获取定位元素的属性值

定位到元素后,获取属性值

element.get_attribute(value)
8、滑动、滚动和拖拽事件
  • 方法名:swipe。滑动事件,从一个坐标滑动到另外一个坐标,只能在两点之前滑动。
#  start_x : 起点x坐标
#  start_y :起点y坐标
#  end_x :终点x坐标
#  end_y :终点y坐标
#  duration=None :滑动这个操作一个持续的时间长度,单位:ms
driver.swipe(start_x,start_y,end_x,end_y,duration=None)

注意:滑动的时候有误差,滑动持续时间越长误差越小,可以理解为惯性,滑动时间越短,惯性就越大。

  • 方法名:scroll。滚动事件,从一个元素滑动到另外一个元素,知道页面自动停止。
#  origin_el :开始元素
#  destination_el :结束元素
driver.scroll(origin_el,destination_el)

注意:此方法不能设置滑动时间,惯性比较大

  • 方法名:drag_and_drop。拖拽事件,从一个元素滑动到另外一个元素,但是注意是第二个元素位置替换第一个元素位置。
#  origin_el :开始元素
#  destination_el :结束元素
driver.drag_and_drop(origin_el,destination_el)

注意:此方法不能设置滑动时间,但无惯性。

  • 三种方法的选择:

    场景 方法选择
    传入元素,且有惯性 scroll
    传入元素,无惯性 drag_and_drop
    传入坐标,有惯性 swipe,设置较短的滑动时间
    传入坐标,无惯性 swipe,设置较长的滑动时间
9、TouchAction操作
  • 操作步骤:首先是找到要操作的元素,然后创建TouchAction对象,接着调用要执行的操作,最后用perform执行操作。

  • 敲击操作,方法:tag(self, element=None, x=None, y=None, count=1),注意,元素和坐标选其一即可。

# element是找到要操作的元素
# x,y是坐标
# count是点击次数
tag(self, element=None, x=None, y=None, count=1)
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction

#找到要操作的元素
setting_bnt = driver.find_element_by_id('XXX')
#首先是创建TouchAction对象
touch_action = TouchAction(driver)
# 然后调用要执行的操作
touch_action = touch_action.tap(setting_bnt)
# 最后用perform执行操作
touch_action.perform()

代码优化后:

setting_bnt = driver.find_element_by_id('XXX')
touch_action = TouchAction(driver).tap(setting_bnt).perform()
  • 按下操作:也就是模拟手指按下,方法为:press(self, el=None, x=None, y=None,)
# el是找到要操作的元素
# x,y是坐标
# count是点击次数
press(self, el=None, x=None, y=None)
TouchAction(driver).press(self, el=None, x=None, y=None, pressure=None).perform()
  • 抬起操作:也就是模拟手指按下后手指再抬起操作,若按下的时间比较短,其实和敲击tap是一样的效果。方法为:release()
TouchAction(driver).press(self, el=None, x=None, y=None, pressure=None).release().perform()
  • 等待操作:模拟手指按下后等待操作。方法:wait(ms=0)。
#默认为0毫秒
wait(ms=0)
TouchAction(driver).press('XXX').wait(2000).release().perform()
  • 长按操作:模拟手指长按元素的操作。方法:long_press(self, el=None, x=None, y=None, duration=1000)
# el是找到要操作的元素
# x,y是坐标
# duration是长按时间
long_press(self, el=None, x=None, y=None, duration=1000)
TouchAction(driver).long_press('XXX',duration=2000).perform()

其实等价于press的如下操作,而long_press相当于自带了抬手操作

TouchAction(driver).press('XXX').wait(2000).release().perform()

  • 移动操作:模拟手机在手机屏幕上移动,方法:move_to(self, el=None, x=None, y=None)
# el是找到要操作的元素
# x,y是坐标
move_to(self, el=None, x=None, y=None)

TouchAction(driver).move_to(x=100,y=250).perform()

注意:移动到目标位置有时是算绝对路径,有时是基于前面一个坐标点的偏移量,这要根据具体的app来进行选择。

示例:

from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support.wait import WebDriverWait
import time

#启动参数
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5'
desired_caps['deviceName'] = 'Android Emulator'
# 包名
desired_caps['appPackage'] = 'com.android.settings'
# 界面名或者启动名
desired_caps['appActivity'] = '.Settings'

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

#定位
def get_element(loca):
    return WebDriverWait(driver,5,0.5).until(lambda x:x.find_element_by_xpath(loca))

#move_to滑动
TouchAction(driver).press(x=182,y=624).move_to(x=539,y=624).move_to(x=539,y=983).perform()

time.sleep(2)
driver.quit()
10、截图操作

模拟人在操作手机进行截图,在进行自动化测试的时候可以对出现bug的页面进行截图,帮助定位和分析bug。

方法:get_screenshot_as_file(self, filename)

driver.get_screenshot_as_file('test.png')
11、获取手机分辨率

在测试的时候,一般手机的机型特别多,而且手机分辨率也各式各样,为了用普世的方法去精确定位元素在屏幕上的位置,一般需要获取屏幕的分辨率并进行计算,便于得到点击或者滑动的坐标。

方法:get_window_size(self, windowHandle='current')

driver.get_window_size()
12、获取和设置手机网络状态
  • 获取手机网络:获取当前手机网络所处于哪一种网络设置。方法:network_connection

获取手机网络值所代表的意思(connection_type):

模式值 数据网络 wifi网络 飞行模式
0(什么都不是) 0 0 0
1(飞行模式) 0 0 1
2(wifi模式) 0 1 0
4(数据模式) 1 0 0
6(数据模式和WiFi模式) 1 1 0
driver.network_connection

  • 设置网络:设置当前手机的网络环境。方法:set_network_connection(self, connection_type)
driver.set_network_connection(6)

注意:一般情况下,程序在进行判断当前手机网络时,并不是用数字,因为数字可读性太差,不便于阅读,而是使用系统提高的可读性较好的方法进行处理。具体如下:

from appium.webdriver.connectiontype import ConnectionType

class ConnectionType(object):
    NO_CONNECTION = 0
    AIRPLANE_MODE = 1
    WIFI_ONLY = 2
    DATA_ONLY = 4
    ALL_NETWORK_ON = 6

13、发送键到设备

模拟人操作手机按键,比如调整音调大小,或者双击返回键等等。

方法:press_keycode( keycode, metastate=None, flags=None)

#keycode (int): the keycode to be sent to the device 发送给设备的关键代码
#metastate (:obj:`int`, optional): meta information about the keycode being sent 关于被发送关键代码的元信息,一般为默认,可以不填。
#flags (:obj:`int`, optional): the set of key event flags

press_keycode(keycode, metastate=None, flags=None)

使用:

driver.press_keycode(4)
14、开启和关闭通知栏
  • 开启通知栏,方法:open_notifications()
driver.open_notifications()
  • 关闭通知栏,方法其实和人操作手机一样,一般就是向上滑动通知栏,或者是按返回键
driver.press_keycode(4)
15、发送文件到手机

通过push_file方法,可以将文件发送至手机

driver.push_file(path,data)

'''
path:文件路径
data:数据文件
'''

示例:

import base64

data1 = 'this is a test'

#base64编码
data = str(base64.b64encode(data.encode('utf-8')),'utf-8')
driver.push_file('/sdcard/123456.txt',data)

由于,输入的base64编码字符串必须符合base64的padding规则,否则程序会报padding错误。“当原数据长度不是3的整数倍时, 如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。”

import base64

def base64_handle(data):
    if (len(data) % 3 == 1):
        data += "=="
    elif (len(data) % 3 == 2):
        data += "="
        
    #base64编码
    data = str(base64.b64encode(data.encode('utf-8')),'utf-8')
    return data

data1 = 'this is a test'
data = base64_handle(data1)
driver.push_file('/sdcard/123456.txt',data)

16、从手机中拉取文件

通过pull_file方法,可以将文件发送至手机

pull_file(path)
'''
path:文件路径
'''

示例:

import base64

data = driver.pull_file(path)
#base64解码
data = str(base64.b64decode(data),'utf-8')
print(data)

注意,被拉取文件需要是相同的编码格式,否则打印出来的信息可能是乱码。

17、获取当前页面内的元素
driver.page_source
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容