Airtest之安卓API汇总

上期回顾:Airtest核心API汇总


上期分享了Airtest核心API,里面有些API是全平台能用,有些是单平台的。本期我们单独看看安卓平台的API,会发现有些API和Airtest核心API相同,其实就是Airtest核心API调用的安卓平台的API。

以下基于airtest1.2.0


Airtest核心API文件路径:
your_python_path/site-packages/airtest/core/api.py


安卓API文件路径:
your_python_path/site-packages/airtest/core/android/android.py

android.py中定义了一个Android类,继承自Device基类,Device类里只有方法名定义,具体实现是在各个设备类里,比如Android的实现就是在android.py中的Android类里。
初始化方法里定义了很多类变量,比如cap方式、输入法、adb等,这个自己看代码吧,下面我们重点介绍一下安卓类里都有哪些方法。

def __init__(self, serialno=None, host=None,
             cap_method=CAP_METHOD.MINICAP,
             touch_method=TOUCH_METHOD.MINITOUCH,
             ime_method=IME_METHOD.YOSEMITEIME,
             ori_method=ORI_METHOD.MINICAP,
             display_id=None,
             input_event=None):
    super(Android, self).__init__()
    self.serialno = serialno or self.get_default_device()
    self._cap_method = cap_method.upper()
    self._touch_method = touch_method.upper()
    self.ime_method = ime_method.upper()
    self.ori_method = ori_method.upper()
    self.display_id = display_id
    self.input_event = input_event
    # init adb
    self.adb = ADB(self.serialno, server_addr=host, display_id=self.display_id, input_event=self.input_event)
    self.adb.wait_for_device()
    self.sdk_version = self.adb.sdk_version
    if self.sdk_version >= SDK_VERISON_ANDROID10 and self._touch_method == TOUCH_METHOD.MINITOUCH:
        self._touch_method = TOUCH_METHOD.MAXTOUCH
    self._display_info = {}
    self._current_orientation = None
    # init components
    self.rotation_watcher = RotationWatcher(self.adb, self.ori_method)
    self.yosemite_ime = YosemiteIme(self.adb)
    self.recorder = Recorder(self.adb)
    self._register_rotation_watcher()

    self._touch_proxy = None
    self._screen_proxy = None

1.touch_proxy
根据self.touch_method的类型,执行对应的触摸操作

Module: 
airtest.core.android.touch_methods.touch_proxy.TouchProxy

返回
TouchProxy

实际案例

dev = Android()
# If the device uses minitouch, it is the same as dev.minitouch.touch
dev.touch_proxy.touch((100, 100))  
dev.touch_proxy.swipe_along([(0,0), (100, 100)])

2.touch_method
为了兼容以前的dev.touch_method

返回
“MINITOUCH” or “MAXTOUCH”

实际案例

dev = Android()
print(dev.touch_method)  # "MINITOUCH"

3.cap_method
为了兼容以前的dev.cap_method

返回
“MINICAP” or “JAVACAP”

实际案例

dev = Android()
print(dev.cap_method)  # "MINICAP"

4.screen_proxy
类似touch_proxy,返回一个代理,能够自动初始化一个可用的屏幕截图方法,例如Minicap
后续只需要调用 self.screen_proxy.get_frame()即可获取到屏幕截图

返回
ScreenProxy(Minicap())

实际案例

dev = Android()
# dev.minicap.get_frame_from_stream() is deprecated
img = dev.screen_proxy.get_frame_from_stream()  

5.get_default_device()
获取本地默认连接的设备,当没有传入设备序列号时

返回
本地设备序列号serialno


6.uuid
返回设备序列号,同adb devices

示例:

print(G.DEVICE.uuid)

7.list_app(third_only=False)
返回packages列表,底层命令为

adb shell pm list packages

参数:    
third_only – 如果为True,只返回所有第三方应用列表

返回:    
应用列表

示例:

print(G.DEVICE.list_app())  # 打印所有包名
print(G.DEVICE.list_app(third_only=True))  # 打印所有第3方包名

8.path_app(package)
打印出package的完整路径,底层命令为

adb shell pm path package_name

参数:    
package – package name

返回:    
package的完整路径

示例:

print(G.DEVICE.path_app("com.netease.cloudmusic"))

9.check_app(package)
检查package在设备中是否存在,底层命令为

adb shell dumpsys package_name

参数:    
package – package name

返回:    
如果存在,返回True

Raises:    
AirtestError – raised if package is not found

示例:

print(G.DEVICE.check_app("com.netease.cloudmusic"))

10.start_app(package, activity=None)
启动应用,底层命令为

adb shell monkey -p package_name -c android.intent.category.LAUNCHER 1
adb shell am start -n package_name/package_name.activity_name

参数:    
package – package name
activity – activity name

返回:    
None

示例:

start_app("com.qasite.www")  # 启动app
start_app("com.qasite.www/com.qasite.www.activity_name")  # 启动app的特定activity

如何获取activity名,安卓和ios分别看:Airtest之使用Poco测试Android原生应用
Airtest之使用Poco测试iOS原生应用


11.start_app_timing(package, activity)
启动应用,并且返回启动耗费时间,底层命令为

adb shell am start -S -W package_name/activity_name -c android.intent.category.LAUNCHER -a android.intent.action.MAIN

参数:    
package – package name
activity – activity name

返回:    
app启动时间

示例:

print(G.DEVICE.start_app_timing("com.miui.calculator","com.miui.calculator.cal.CalculatorActivity"))
# 结果为420

12.stop_app(package)
停止应用,底层命令为

adb shell am force-stop package_name

参数:    
package – package name

返回:    
None

示例:

stop_app("com.netease.cloudmusic")

13.clear_app(package)
清理应用数据(想当于重装了app),底层命令为

adb shell pm clear package_name

参数:    
package – package name

返回:    
None

示例:

clear_app("com.netease.cloudmusic")

14.install_app(filepath, replace=False, install_options=None)
将应用安装到手机上,底层命令为

adb install

参数:    
filepath – apk 文件在PC上的完整路径
replace – 如果应用已存在,是否替换,即install的参数-r
install_options – install命令的额外选项,默认是[],有以下参数:

"-t",  # allow test packages
"-l",  # forward lock application,
"-s",  # install application on sdcard,
"-d",  # allow version code downgrade (debuggable packages only)
"-g",  # grant all runtime permissions

返回:    
安装进程的输出内容

示例:

install_app("com.netease.cloudmusic")  # 安装app
install_app("com.netease.cloudmusic", replace=True)  # 用新包覆盖安装app

15.uninstall_app(package)
从设备中卸载应用,底层命令为

adb uninstall

参数:    
package – package name

返回:    
卸载进程中的输出内容

示例:

uninstall("com.netease.cloudmusic")

16.snapshot(filename=None, ensure_orientation=True, quality=10, max_size=None)
截取一张当前手机画面,默认会发送到stdout

参数:    
filename – 保存截图的文件名,默认为None的话将会发送到stdout
ensure_orientation – 截图方向是否要与当前显示情况一致,默认为True
quality – 截图质量,整数,范围为[1, 99]
max_size – 截图最大尺寸, e.g 1200

返回:    
截图输出

示例:
详见上期Airtest核心API


17.shell(*args, **kwargs)
大部分adb命令airtest已经封装好了,如果有没有封装的,可以用这个执行自己的adb shell命令。

参数:    
*args – optional shell commands
**kwargs – optional shell commands

返回:    
None

示例:

print(G.DEVICE.shell("pwd"))
print(G.DEVICE.shell("ls"))

18.keyevent(keyname, **kwargs)
在设备上执行keyevent,底层命令为

adb shell input keyevent

参数:    
keyname – keyevent name
**kwargs – optional arguments

返回:    
None

示例:

G.DEVICE.keyevent("66")  # 输入回车键

keyevent code可参考adb shell input keyevent键值大全


19.wake()
通过yosemite执行唤醒操作,部分机型无效

返回:    
None


20.home()
按下HOME键,其实就是上面的keyevent("HOME")

返回:    
None


21.text(text, enter=True, **kwargs)
向设备中输入字符串

参数:    
text – 要输入的字符串
enter – 是否按下Enter
search – 是否要按下输入法键盘中的search键

返回:    
None

示例:

text("公众号:测试工程师小站")  # 输入并点击回车按钮
text("公众号:测试工程师小站", enter=False)  # 输入
text("公众号:测试工程师小站", search=True)  # 输入并点击搜索按钮

22.touch(pos, duration=0.01)
在设备上执行点击

参数:    
pos – 绝对坐标(x, y)
duration – 点击屏幕的时长

返回:    
None

示例:

touch((100, 100))  # 点击100,100,持续0.01秒
touch((100, 100), duration=2)  # 点击100,100,持续2秒

23.double_click(pos)
其实就是调用了2次touch(),可以看源码

self.touch(pos)
time.sleep(0.05)
self.touch(pos)

24.swipe(p1, p2, duration=0.5, steps=5, fingers=1)
在设备上执行滑动操作

参数:    
p1 – 开始坐标
p2 – 结束坐标
duration – 在屏幕上滑动的时长,默认是0.5
steps – 滑动过程中的步数,默认为5
fingers – 滑动的手指数量,1或者2,默认为1

返回:    
None

示例:

# 从绝对坐标(100,500)滑到(500,500)
G.DEVICE.swipe((100,500),(500,500))

# 用两指从绝对坐标(100,500)滑到(500,500)
G.DEVICE.swipe((100,500),(500,500), fingers=2)

# 从绝对坐标(100,500)分六步滑到(500,500),整个持续时间3秒
G.DEVICE.swipe((100,500),(500,500), duration=3, steps=6)

25.pinch(center=None, percent=0.5, duration=0.5, steps=5, in_or_out='in')
在设备上执行pinch操作(放大缩小),仅适用于minitouch和maxtouch

参数:    
center – pinch操作的中心点
percent – pinch操作捏合屏幕的距离,默认是0.5
duration – 滑动过程中的时间间隔,默认是0.8
steps – 滑动过程中的步数,默认为5
in_or_out – 向内捏合in或者向外捏合out,默认是’in’

返回:    
None

Raises:    
TypeError – An error occurred when center is not a list/tuple or None

示例:

# 操作的坐标点、执行的距离、放大/缩小这些需要调试才能执行成功,自己多试几次找找规律。

# 从绝对坐标(500,500)往外执行放大操作,持续时间3秒
G.DEVICE.pinch(center=(500,500), duration=3, in_or_out='out')

# 从绝对坐标(600,600)往里执行缩小操作,分为5步,距离为0.4
G.DEVICE.pinch(center=(600,600), percent=0.4, steps=5, in_or_out='in')

26.swipe_along(coordinates_list, duration=0.8, steps=5)
执行一段连续的滑动操作(如九宫格解锁),仅适用于minitouch和maxtouch

参数:    
coordinates_list – 一个坐标的列表:[(x1, y1), (x2, y2), (x3, y3)]
duration – 滑动过程中的时间间隔,默认是0.8
steps – 滑动过程中的步数,默认为5

返回:    
None

示例:

# 从(100, 100)滑到(100, 500),再从(100, 500)滑到(500, 500);2次滑动每次都持续3秒&分为4步
G.DEVICE.swipe_along([(100, 100), (100, 500), (500, 500)], duration=3, steps=4)

27.two_finger_swipe(tuple_from_xy, tuple_to_xy, duration=0.8, steps=5, offset=(0, 50))
执行两个手指一起滑动的操作,仅适用于minitouch和maxtouch

参数:    
tuple_from_xy – 开始坐标
tuple_to_xy – 结束坐标
duration – 滑动过程中的时间间隔,默认是0.8
steps – 滑动过程中的步数,默认为5
offset – 第二个手指相对于第一个手指的偏移坐标,默认是(0, 50)

返回:    
None

示例:

# 横滑:手指1从(100, 500)滑到(800, 500),手指2从(100, 550)滑到(800, 550),同时滑,持续3秒,分4步
G.DEVICE.two_finger_swipe((100, 500), (800, 500), duration=3, steps=4)

# 竖滑:手指1从(500, 100)滑到(500, 800),手指2从(550, 100)滑到(550, 800),同时滑,持续0.8秒,分5步
G.DEVICE.two_finger_swipe((500, 100), (500, 800), offset=(50, 0))

28.logcat(grep_str="", extra_args="", read_timeout=10)
执行 logcat,底层命令为

adb shell logcat

参数:    
grep_str – 要过滤的字符,底层是用|grep
extra_args – adb shell logcat后面要额外添加的命令,如">log.txt"
read_timeout - 持续时间,默认10秒

返回:    
logcat 输出

示例:

# adb shell logcat *:W | grep error
# 执行logcat设置过滤级别为W以上,再在结果中再过滤error关键字,持续60秒
G.DEVICE.logcat("error", "*:W", 60)

29.getprop(key, strip=True)
根据传入的key获取properties内容,底层命令为

adb shell getprop

参数:    
key – key name
strip – 是否对输出内容进行strip

返回:    
property value(s)


30.get_ip_address()
执行以下几种命令行来获取IP地址

adb shell netcfg | grep wlan0
adb shell ifconfig
adb getprop dhcp.wlan0.ipaddress

返回:    
如果获取IP失败,返回None,否则返回IP地址


31.get_top_activity()
获取当前activity数据,底层命令为

adb shell dumpsys activity top

返回:    
(package, activity, pid)


32.get_top_activity_name()
获取当前activity名称,其实就是调用了上一个函数后重组了返回值

返回:    
如果获取失败,返回None,否则返回"package/activity"


33.is_keyboard_shown()
如果软键盘正在启用,返回True,否则False,底层命令为

adb shell dumpsys input_method

Notes
不一定在所有设备上都可用

返回:    
True or False


34.is_screenon()
如果屏幕是亮着的,返回True,否则False,底层命令为

adb shell dumpsys window policy

Notes
不一定在所有设备上都可用

返回:    
True or False


35.is_locked()
如果是锁定状态返回True,否则False,底层命令为

adb shell dumpsys window policy

Notes
部分设备上可能不可用

返回:    
True or False


36.unlock()
解锁设备,底层命令为

adb shell input keyevent MENU
adb shell input keyevent BACK

Notes
不一定在所有设备上都可用

返回:    
None


37.get_display_info()
返回显示信息(width, height, orientation 和 max_x, max_y)

返回
显示信息,如

{'width': 1080, 'height': 2400, 'density': 2.75, 'orientation': 1, 'rotation': 90, 'max_x': 1079, 'max_y': 2399}

38.display_info
返回显示信息。@property只读属性,就是调用了上面的get_display_info()

返回:    
显示信息,如

{'width': 1080, 'height': 2400, 'density': 2.75, 'orientation': 1, 'rotation': 90, 'max_x': 1079, 'max_y': 2399}

39.get_current_resolution()
返回旋转后的当前分辨率

返回:    
宽, 高,如(2400, 1080)


40.get_render_resolution(refresh=False)
返回旋转后的渲染分辨率

参数:    
refresh – 是否强制刷新渲染分辨率

返回:    
offset_x, offset_y, offset_width and offset_height of the display
如(95.0, 0.0, 2305.0, 1080.0),其原始分辨率是2400*1080,返回的这个有差值是因为app有黑边,没有全屏显示


41.start_recording(max_time=1800, bit_rate_level=1, bit_rate=None)
开始对设备画面进行录制

参数:    
max_time – 最大录屏时间, 默认1800秒
bit_rate_level – bit_rate=resolution*level, 0 < level <= 5, default is 1
bit_rate – the higher the bitrate, the clearer the video

返回:    
None

实际案例:

# Record 30 seconds of video and export to the current directory test.mp4:

from airtest.core.api import connect_device, sleep
dev = connect_device("Android:///")
# Record the screen with the lowest quality
dev.start_recording(bit_rate_level=1)
sleep(30)
dev.stop_recording(output="test.mp4")

# Or set max_time=30, the screen recording will stop automatically after 30 seconds:

dev.start_recording(max_time=30, bit_rate_level=5)
dev.stop_recording(output="test_30s.mp4")

# The default value of max_time is 1800 seconds, so the maximum screen recording time is half an hour. 
# You can modify its value to obtain a longer screen recording:

dev.start_recording(max_time=3600, bit_rate_level=5)
dev.stop_recording(output="test_hour.mp4")

42.stop_recording(output='screen.mp4', is_interrupted=False)
停止对设备画面的录制。录制出的文件将会放在设备中。

参数:    
output – default file is screen.mp4
is_interrupted – True or False. Stop only, no pulling recorded file from device.

返回:    
None


43.adjust_all_screen()
对全面屏设备进行渲染分辨率的调整。

返回
None

---------------------------------------------------------------------------------

关注微信公众号即可在手机上查阅,并可接收更多测试分享~

原文地址:https://www.cnblogs.com/songzhenhua/p/15315215.html