definit_device(platform="Android", uuid=None, **kwargs): """ Initialize device if not yet, and set as current device. :param platform: Android, IOS or Windows :param uuid: uuid for target device, e.g. serialno for Android, handle for Windows, uuid for iOS :param kwargs: Optional platform specific keyword args, e.g. `cap_method=JAVACAP` for Android :return: device instance """
示例如下:
1 2
device = init_device('Android') print(device)
运行结果如下:
1
<airtest.core.android.android.Androidobject at 0x1018f3a58>
def connect_device(uri): """ Initialize device with uri, andsetascurrent device.
:param uri: an URI wheretoconnectto device, e.g. `android://adbhost:adbport/serialno?param=value¶m2=value2` :return: device instance :Example: * ``android:///``# local adb device using default params * ``android://adbhost:adbport/1234566?cap_method=javacap&touch_method=adb``# remote device using custom params * ``windows:///``# local Windows application * ``ios:///``# iOS device """
示例如下:
1 2 3 4 5 6
from airtest.core.android import Android from airtest.core.api import *
uri = 'Android://127.0.0.1:5037/emulator-5554' device: Android = connect_device(uri) print(device)
运行结果如下:
1
<airtest.core.android.android.Androidobject at 0x110246940>
defset_current(idx): """ Set current active device. :param idx: uuid or index of initialized device instance :raise IndexError: raised when device idx is not found :return: None :platforms: Android, iOS, Windows """
@logwrap def shell(cmd): """ Start remote shell in the target device andexecute the command
:param cmd: commandtobe run on device, e.g. "ls /data/local/tmp" :return: the output of the shell cmd :platforms: Android """ return G.DEVICE.shell(cmd)
直接调用 adb 命令就好了,例如获取内存信息就可以使用如下命令:
1 2 3 4 5 6 7
fromairtest.core.apiimport *
uri = 'Android://127.0.0.1:5037/emulator-5554' connect_device(uri)
@logwrap def start_app(package, activity=None): """ Start the target application on device
:param package: name of the package to be started, e.g. "com.netease.my" :param activity: the activity to start, default is None which means the main activity :return: None :platforms: Android, iOS """ G.DEVICE.start_app(package, activity)
@logwrap def stop_app(package): """ Stop the target application on device
:param package: name of the package to stop, see also `start_app` :return: None :platforms: Android, iOS """ G.DEVICE.stop_app(package)
用法示例如下:
1 2 3 4 5 6 7 8 9
fromairtest.core.apiimport *
uri = 'Android://127.0.0.1:5037/emulator-5554' connect_device(uri)
@logwrap def install(filepath, **kwargs): """ Install application on device
:param filepath: the path to file to be installed on target device :param kwargs: platform specific `kwargs`, please refer to corresponding docs :return: None :platforms: Android """ return G.DEVICE.install_app(filepath, **kwargs)
@logwrap def uninstall(package): """ Uninstall application on device
:param package: name of the package, see also `start_app` :return: None :platforms: Android """ return G.DEVICE.uninstall_app(package)
截图
截图使用 snapshot 即可完成,可以设定存储的文件名称,图片质量等。 定义如下:
1 2 3 4 5 6 7 8 9 10 11
def snapshot(filename=None, msg="", quality=ST.SNAPSHOT_QUALITY): """ Take the screenshot of the target device and save it to the file.
:param filename: name of the file where to save the screenshot. If the relative path is provided, the default location is ``ST.LOG_DIR`` :param msg: short description for screenshot, it will be recorded in the report :param quality: The image quality, integer in range [1, 99] :return: absolute path of the screenshot :platforms: Android, iOS, Windows """
示例如下:
1 2 3 4 5 6 7 8 9
from airtest.core.api import *
uri = 'Android://127.0.0.1:5037/emulator-5554' connect_device(uri)
@logwrap defwake(): """ Wake up and unlock the target device :return: None :platforms: Android .. note:: Might not work on some models """ G.DEVICE.wake()
@logwrap defhome(): """ Return to the home screen of the target device. :return: None :platforms: Android, iOS """ G.DEVICE.home()
直接调用即可。
点击屏幕
点击屏幕是 touch 方法,可以传入一张图或者绝对位置,同时可以指定点击次数,定义如下:
1 2 3 4 5 6 7 8 9 10 11
@logwrap def touch(v, times=1, **kwargs): """ Perform the touch action on the device screen
:param v: target to touch, either a Template instance or absolute coordinates (x, y) :param times: how many touches tobe performed :param kwargs: platform specific `kwargs`, please refer to corresponding docs :return: finial position tobe clicked :platforms: Android, Windows, iOS """
@logwrap def swipe(v1, v2=None, vector=None, **kwargs): """ Perform the swipe action on the device screen.
There are two ways of assigning the parameters * ``swipe(v1, v2=Template(...))`` # swipe from v1 to v2 * ``swipe(v1, vector=(x, y))`` # swipe starts at v1 and moves along the vector.
:param v1: the start point of swipe, either a Template instance or absolute coordinates (x, y) :param v2: the end point of swipe, either a Template instance or absolute coordinates (x, y) :param vector: a vector coordinates of swipe action, either absolute coordinates (x, y) or percentage of screen e.g.(0.5, 0.5) :param **kwargs: platform specific `kwargs`, please refer to corresponding docs :raise Exception: general exception when not enough parameters to perform swap action have been provided :return: Origin position and target position :platforms: Android, Windows, iOS """
比如这里我们可以定义手指向右滑动:
1 2 3 4 5 6
from airtest.core.api import *
uri = 'Android://127.0.0.1:5037/emulator-5554' connect_device(uri) home() swipe((200, 300), (900, 300))
@logwrap def pinch(in_or_out='in', center=None, percent=0.5): """ Perform the pinch action on the device screen
:param in_or_out: pinch in or pinch out, enum in ["in", "out"] :param center: center of pinch action, default as None which is the center of the screen :param percent: percentage of the screen of pinch action, default is0.5 :return: None :platforms: Android """
示例如下:
1 2 3 4 5 6
from airtest.core.api import *
uri = 'Android://127.0.0.1:5037/emulator-5554' connect_device(uri) home() pinch(in_or_out='out', center=(300, 300), percent=0.4)
defkeyevent(keyname, **kwargs): """ Perform key event on the device :param keyname: platform specific key name :param **kwargs: platform specific `kwargs`, please refer to corresponding docs :return: None :platforms: Android, Windows, iOS """
示例如下:
1
keyevent("HOME")
这样就表示按了 HOME 键。
输入内容
输入内容需要使用 text 方法,当然前提是这个 widget 需要是 active 状态,text 的定义如下:
1 2 3 4 5 6 7 8 9 10
@logwrap def text(text, enter=True, **kwargs): """ Input text on the target device. Text input widget must be active first.
:param text: text toinput, unicode is supported :param enter: input `Enter` keyevent after text input, default is True :return: None :platforms: Android, Windows, iOS """
等待和判断
可以使用 wait 方法等待某个内容加载出来,需要传入的是 Template,定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
@logwrap def wait(v, timeout=None, interval=0.5, intervalfunc=None): """ Wait tomatch the Template on the device screen
:param v: target object to wait for, Template instance :param timeout: time interval to wait for the match, default is None which is ``ST.FIND_TIMEOUT`` :param interval: time interval in seconds to attempt tofindamatch :param intervalfunc: called after each unsuccessful attempt tofind the corresponding match :raise TargetNotFoundError: raised if target is not found after the time limit expired :return: coordinates of the matched target :platforms: Android, Windows, iOS """
同时也使用 exists 方法判断某个内容是否存在,定义如下:
1 2 3 4 5 6 7 8 9
@logwrap defexists(v): """ Check whether given target exists on device screen :param v: target to be checked :return: False if target is not found, otherwise returns the coordinates of the target :platforms: Android, Windows, iOS """
:param v: target to be checked :param msg: short description of assertion, it will be recorded in the report :raise AssertionError: if assertion fails :return: coordinates of the target :platforms: Android, Windows, iOS """ try: pos = loop_find(v, timeout=ST.FIND_TIMEOUT, threshold=ST.THRESHOLD_STRICT) return pos except TargetNotFoundError: raise AssertionError("%s does not exist in screen, message: %s" % (v, msg))
@logwrap def assert_not_exists(v, msg=""): """ Assert target does not exist on device screen
:param v: target to be checked :param msg: short description of assertion, it will be recorded in the report :raise AssertionError: if assertion fails :return: None. :platforms: Android, Windows, iOS """ try: pos = loop_find(v, timeout=ST.FIND_TIMEOUT_TMP) raise AssertionError("%s exists unexpectedly at pos: %s, message: %s" % (v, pos, msg)) except TargetNotFoundError: pass
@logwrap def assert_equal(first, second, msg=""): """ Assert two values are equal
:param first: first value :param second: second value :param msg: short description of assertion, it will be recorded in the report :raise AssertionError: if assertion fails :return: None :platforms: Android, Windows, iOS """ if first != second: raise AssertionError("%s and %s are not equal, message: %s" % (first, second, msg))
@logwrap def assert_not_equal(first, second, msg=""): """ Assert two values are not equal
:param first: first value :param second: second value :param msg: short description of assertion, it will be recorded in the report :raise AssertionError: if assertion :return: None :platforms: Android, Windows, iOS """ if first == second: raise AssertionError("%s and %s are equal, message: %s" % (first, second, msg))
这几个断言比较常用的就是 assert_exists 和 assert_not_exists 判断某个目标是否存在于屏幕上,同时还可以传入 msg,它可以被记录到 report 里面。 以上就是 Airtest 的 API 的用法,它提供了一些便捷的方法封装,同时还对接了图像识别等技术。 但 Airtest 也有一定的局限性,比如不能根据 DOM 树来选择对应的节点,依靠图像识别也有一定的不精确之处,所以还需要另外一个库 —— Poco。
Poco
利用 Poco 我们可以支持 DOM 选择,例如编写 XPath 等来定位某一个节点。 首先需要安装 Poco,使用 pip3 即可: