前言
最近在学习uiautomator2,这是一款开源的UI自动化测试框架,可结合Python用于Android应用的自动化测试。
uiautomator2,其底层基于谷歌下的uiautomator库进行了封装,提供了便利的Python接口,允许测试人员直接在PC上编写Python代码,来获取屏幕上任一App的任意控件属性,并对其进行任意操作,极大提高了自动化代码编写的效率。
更多的介绍,大家可以前往 Github 进行学习:https://github.com/openatx/uiautomator2
uiautomator2支持 Python2 和 Python3.x ,但该项目作者目前不再对 Python 3.6 以下的版本使用进行维护,我们最好使用 Python 3.6+ 版本来进行学习和实践。
安装 ADB
命令行窗口下,输入命令:adb devices,如果出现报错则说明未安装配置好adb相关环境。
如果未安装 adb,那么需要到谷歌官网下载 Android SDK Platform Tools,地址:https://developer.android.com/studio/releases/platform-tools.html,下载并解压,完成后把包含 adb.exe 的目录添加到系统的环境变量PATH中。如果上面地址访问不了,也可以通过下面的链接获取文件。
链接:https://pan.baidu.com/s/18ex49zLLB0UBDsylxhYX0g
提取码:4fq1
安装 uiautomator2
通过 Python 的 pip 工具进行安装,命令如下:pip install --pre -U uiautomator2 。
(venv) D:\pycharm\Code\atxDemo2\venv\Scripts>pip install --pre -U uiautomator2
Collecting uiautomator2
Downloading https://files.pythonhosted.org/packages/3a/3d/731395da6692447598786f35a6921f816498dcdaf7247aaf5d788a2a11a8/uiautomator2-2.15.2.tar.gz (677kB)
100% |████████████████████████████████| 686kB 7.8kB/s
Collecting six (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl
Collecting requests (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/29/c1/24814557f1d22c56d50280771a17307e6bf87b70727d975fd6b2ce6b014a/requests-2.25.1-py2.py3-none-any.whl (61kB)
100% |████████████████████████████████| 61kB 6.0kB/s
Collecting whichcraft (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/b5/a2/81887a0dae2e4d2adc70d9a3557fdda969f863ced51cd3c47b587d25bce5/whichcraft-0.6.1-py2.py3-none-any.whl
Collecting logzero~=1.5 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl
Collecting progress~=1.3 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/38/ef/2e887b3d2b248916fc2121889ce68af8a16aaddbe82f9ae6533c24ff0d2b/progress-1.5.tar.gz
Collecting retry~=0.9 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/4b/0d/53aea75710af4528a25ed6837d71d117602b01946b307a3912cb3cfcbcba/retry-0.9.2-py2.py3-none-any.whl
Collecting adbutils<1.0,>=0.11.0 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/e7/d7/cf5d49c69ebc480c4422ead0d16e22c22df0a0bd6cfd1ae292f7499568fe/adbutils-0.11.0-py3-none-win_amd64.whl (1.4MB)
100% |████████████████████████████████| 1.4MB 5.7kB/s
Collecting Deprecated~=1.2.6 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/fb/73/994edfcba74443146c84b91921fcc269374354118d4f452fb0c54c1cbb12/Deprecated-1.2.12-py2.py3-none-any.whl
Collecting Pillow (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/84/41/b233abcfb9bae12768bffae92e2c96d2d807cd92a3cef7d24987df0e3d64/Pillow-8.2.0-cp37-cp37m-win_amd64.whl (2.2MB)
100% |████████████████████████████████| 2.2MB 27kB/s
Collecting lxml>=4.3 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/9e/5e/171ee9d40a600f565fe691ec5bf7596247ec62cfb2edc00c91afe8ea837b/lxml-4.6.3-cp37-cp37m-win_amd64.whl (3.5MB)
100% |████████████████████████████████| 3.5MB 7.5kB/s
Collecting cached-property<2.0,>=1.5.1 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/48/19/f2090f7dad41e225c7f2326e4cfe6fff49e57dedb5b53636c9551f86b069/cached_property-1.5.2-py2.py3-none-any.whl
Collecting packaging~=20.3 (from uiautomator2)
Downloading https://files.pythonhosted.org/packages/3e/89/7ea760b4daa42653ece2380531c90f64788d979110a2ab51049d92f408af/packaging-20.9-py2.py3-none-any.whl (40kB)
100% |████████████████████████████████| 40kB 4.4kB/s
Collecting urllib3<1.27,>=1.21.1 (from requests->uiautomator2)
Downloading https://files.pythonhosted.org/packages/09/c6/d3e3abe5b4f4f16cf0dfc9240ab7ce10c2baa0e268989a4e3ec19e90c84e/urllib3-1.26.4-py2.py3-none-any.whl (153kB)
100% |████████████████████████████████| 153kB 12kB/s
Collecting chardet<5,>=3.0.2 (from requests->uiautomator2)
Downloading https://files.pythonhosted.org/packages/19/c7/fa589626997dd07bd87d9269342ccb74b1720384a4d739a1872bd84fbe68/chardet-4.0.0-py2.py3-none-any.whl (178kB)
100% |████████████████████████████████| 184kB 5.9kB/s
Collecting certifi>=2017.4.17 (from requests->uiautomator2)
Downloading https://files.pythonhosted.org/packages/5e/a0/5f06e1e1d463903cf0c0eebeb751791119ed7a4b3737fdc9a77f1cdfb51f/certifi-2020.12.5-py2.py3-none-any.whl (147kB)
100% |████████████████████████████████| 153kB 7.8kB/s
Collecting idna<3,>=2.5 (from requests->uiautomator2)
Downloading https://files.pythonhosted.org/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl (58kB)
100% |████████████████████████████████| 61kB 8.2kB/s
Collecting colorama; sys_platform == "win32" (from logzero~=1.5->uiautomator2)
Downloading https://files.pythonhosted.org/packages/44/98/5b86278fbbf250d239ae0ecb724f8572af1c91f4a11edf4d36a206189440/colorama-0.4.4-py2.py3-none-any.whl
Collecting decorator>=3.4.2 (from retry~=0.9->uiautomator2)
Downloading https://files.pythonhosted.org/packages/6a/36/b1b9bfdf28690ae01d9ca0aa5b0d07cb4448ac65fb91dc7e2d094e3d992f/decorator-5.0.9-py3-none-any.whl
Collecting py<2.0.0,>=1.4.26 (from retry~=0.9->uiautomator2)
Downloading https://files.pythonhosted.org/packages/67/32/6fe01cfc3d1a27c92fdbcdfc3f67856da8cbadf0dd9f2e18055202b2dc62/py-1.10.0-py2.py3-none-any.whl (97kB)
100% |████████████████████████████████| 102kB 8.8kB/s
Collecting apkutils2<2.0,>=1.0.0 (from adbutils<1.0,>=0.11.0->uiautomator2)
Downloading https://files.pythonhosted.org/packages/e5/d0/432fb6fb1fe48aa0ea1c80e8dec4a26f70c868999c076f92af88582ae91a/apkutils2-1.0.0.tar.gz (60kB)
100% |████████████████████████████████| 61kB 9.6kB/s
Collecting deprecation<3.0,>=2.0.6 (from adbutils<1.0,>=0.11.0->uiautomator2)
Downloading https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl
Collecting wrapt<2,>=1.10 (from Deprecated~=1.2.6->uiautomator2)
Downloading https://files.pythonhosted.org/packages/82/f7/e43cefbe88c5fd371f4cf0cf5eb3feccd07515af9fd6cf7dbf1d1793a797/wrapt-1.12.1.tar.gz
Collecting pyparsing>=2.0.2 (from packaging~=20.3->uiautomator2)
Downloading https://files.pythonhosted.org/packages/ff/c5/14a5edf227544a6da3cb99a1481fc894db9a81306c9a18b736d3ac9fe8d5/pyparsing-3.0.0b2-py3-none-any.whl (84kB)
100% |████████████████████████████████| 92kB 5.8kB/s
Collecting pyelftools (from apkutils2<2.0,>=1.0.0->adbutils<1.0,>=0.11.0->uiautomator2)
Downloading https://files.pythonhosted.org/packages/6f/50/3d7729d64bb23393aa4c166af250a6e6f9def40c90bf0e9af3c5ad25b6f7/pyelftools-0.27-py2.py3-none-any.whl (151kB)
100% |████████████████████████████████| 153kB 7.7kB/s
Collecting cigam (from apkutils2<2.0,>=1.0.0->adbutils<1.0,>=0.11.0->uiautomator2)
Downloading https://files.pythonhosted.org/packages/3c/d0/19ff49c1938aea4e0076ee084ca23845408cffb51582b2be975f926533b5/cigam-0.0.3-py3-none-any.whl
Collecting xmltodict (from apkutils2<2.0,>=1.0.0->adbutils<1.0,>=0.11.0->uiautomator2)
Downloading https://files.pythonhosted.org/packages/28/fd/30d5c1d3ac29ce229f6bdc40bbc20b28f716e8b363140c26eff19122d8a5/xmltodict-0.12.0-py2.py3-none-any.whl
Installing collected packages: six, urllib3, chardet, certifi, idna, requests, whichcraft, colorama, logzero, progress, decorator, py, retry, pyelftools, cigam, xmltodict, apkutils2, pyparsing, packaging, deprecation, adbutils, wrapt, Deprecated, Pillow, lxml, cached-property, uiautomator2
Running setup.py install for progress ... done
Running setup.py install for apkutils2 ... done
Running setup.py install for wrapt ... done
Running setup.py install for uiautomator2 ... done
Successfully installed Deprecated-1.2.12 Pillow-8.2.0 adbutils-0.11.0 apkutils2-1.0.0 cached-property-1.5.2 certifi-2020.12.5 chardet-4.0.0 cigam-0.0.3 colorama-0.4.4 decorator-5.0.9 deprecation-2.1.0 idna-2.10 logzero-1.7.0 lxml-4.6.3 packaging-20.9 progress-1.5 py-1.10.0 pyelftools-0.27 pyparsing-3.0.0b2 requests-2.25.1 retry-0.9.2 six-1.16.0 uiautomator2-2.15.2 urllib3-1.26.4 whichcraft-0.6.1 wrapt-1.12.1 xmltodict-0.12.0
You are using pip version 10.0.1, however version 21.1.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
安装 atx-agent
首先,确保手机已经连接到电脑,输入命令:adb devices 查看连接状态,如果显示出手机 device 序列号,那么表示连接成功。
D:\>adb devices
List of devices attached
c01bcd5d device
最后,输入命令:python -m uiautomator2 init 进行 atx-agent 初始化。
(venv) D:\pycharm\Code\atxDemo2\venv\Scripts>python -m uiautomator2 init
[I 210516 17:32:39 init:156] uiautomator2 version: 2.15.2
[I 210516 17:32:39 init:351] Install minicap, minitouch
[D 210516 17:32:39 init:59] Use cached assets: C:\Users\wintest\.uiautomator2\cache\minitouch-f7a806902f\minitouch
[D 210516 17:32:39 init:237] Push to /data/local/tmp/minitouch:0755
[D 210516 17:32:39 init:59] Use cached assets: C:\Users\wintest\.uiautomator2\cache\minicap.so-031700ed26\minicap.so
[D 210516 17:32:39 init:237] Push to /data/local/tmp/minicap.so:0755
[D 210516 17:32:40 init:59] Use cached assets: C:\Users\wintest\.uiautomator2\cache\minicap-4ad740a772\minicap
[D 210516 17:32:40 init:237] Push to /data/local/tmp/minicap:0755
[D 210516 17:32:40 init:255] apk-debug package-info: None
[D 210516 17:32:40 init:256] apk-debug-test package-info: {'package_name': 'com.github.uiautomator.test', 'version_name': '', 'version_code': '', 'flags': ['DEBUGGABLE', 'HAS_CODE', 'ALLOW_CLEAR_USER_DATA', 'ALLOW_BACKUP'], 'first_install_time': datetime.datetime(2021, 3, 18, 21, 42, 21), 'last_update_time': datetime.datetime(2021, 3, 18, 21, 42, 21), 'signature': '8376b3fb'}
[I 210516 17:32:40 init:366] Install com.github.uiautomator, com.github.uiautomator.test 2.3.3
[D 210516 17:32:40 init:167] Shell: ('pm', 'uninstall', 'com.github.uiautomator')
[D 210516 17:32:41 init:167] Shell: ('pm', 'uninstall', 'com.github.uiautomator.test')
[D 210516 17:32:43 init:62] Download https://tool.appetizer.io/openatx/android-uiautomator-server/releases/download/2.3.3/app-uiautomator.apk
app-uiautomator.apk |⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿| 2.1 MB/2.1 MB
�[?25h[D 210516 17:32:43 init:237] Push to /data/local/tmp/app-uiautomator.apk:0644
[D 210516 17:32:43 init:167] Shell: ('pm', 'install', '-r', '-t', '/data/local/tmp/app-uiautomator.apk')
[I 210516 17:32:55 init:336] - app-uiautomator.apk installed
[D 210516 17:32:55 init:62] Download https://tool.appetizer.io/openatx/android-uiautomator-server/releases/download/2.3.3/app-uiautomator-test.apk
app-uiautomator-test.apk |⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿| 1.0 MB/1.0 MB
�[?25h[D 210516 17:32:55 init:237] Push to /data/local/tmp/app-uiautomator-test.apk:0644
[D 210516 17:32:55 init:167] Shell: ('pm', 'install', '-r', '-t', '/data/local/tmp/app-uiautomator-test.apk')
[I 210516 17:33:06 init:336] - app-uiautomator-test.apk installed
[D 210516 17:33:06 init:167] Shell: ('/data/local/tmp/atx-agent', 'server', '--stop')
[D 210516 17:33:06 init:295] Real version: [0, 9, 6], Expect version: [0, 10, 0]
[I 210516 17:33:06 init:344] Install atx-agent 0.10.0
[D 210516 17:33:06 init:62] Download https://tool.appetizer.io/openatx/atx-agent/releases/download/0.10.0/atx-agent_0.10.0_linux_armv7.tar.gz
atx-agent_0.10.0_linux_armv7.tar.gz |⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿| 4.1 MB/4.1 MB
�[?25h[D 210516 17:33:07 init:237] Push to /data/local/tmp/atx-agent:0755
[D 210516 17:33:08 init:167] Shell: ('/data/local/tmp/atx-agent', 'server', '--nouia', '-d', '--addr', '127.0.0.1:7912')
[I 210516 17:33:08 init:379] Check atx-agent version
[D 210516 17:33:08 init:392] Forward: local:tcp:49709 -> remote:tcp:7912
[D 210516 17:33:08 init:392] Forward: local:tcp:49709 -> remote:tcp:7912
[D 210516 17:33:09 init:395] atx-agent version 0.10.0
[D 210516 17:33:09 init:398] device wlan ip: 192.168.1.12
Successfully init AdbDevice(serial=c00bad6d)
如果界面显示 Successfully 则说明安装成功,同时手机上会出现一个 ATX 的应用。
连接手机的两种方式
python-uiautomator2 提供了两种方式来连接手机:WiFi 连接
和 USB 连接
- 通过 USB 连接
手机通过USB连接到电脑后,输入命令:adb devices 查看状态并获取手机 device 序列号。然后到命令行中打开Python交互窗口,执行以下命令:
>>> import uiautomator2 as u2
>>> d = u2.connect_usb('c00bad6d')
>>> d.info
[D 210516 17:45:24 __init__:630] kill process(ps): uiautomator
[D 210516 17:45:27 __init__:648] uiautomator-v2 is starting ... left: 40.0s
[D 210516 17:45:28 __init__:648] uiautomator-v2 is starting ... left: 39.0s
[D 210516 17:45:29 __init__:648] uiautomator-v2 is starting ... left: 37.9s
[I 210516 17:45:30 __init__:613] uiautomator back to normal
{'currentPackageName': 'com.sec.android.app.launcher', 'displayHeight': 1920, 'displayRotation': 0, 'displaySizeDpX': 360, 'displaySizeDpY': 640, 'displayWidth': 1080, 'productName': 'hel-2qec', 'screenOn': True, 'sdkInt': 26, 'naturalOrientation': True}
该方式可以用于手机和电脑不在同一网络下的情况,只需要连接上USB数据线就可以实现连接。
- 通过 WiFi 连接
假设当前设备的IP为 192.168.1.12,并和电脑处于同一网络下,在电脑上可以 Ping 通手机的IP。
>>> import uiautomator2 as u2
>>> d = u2.connect('192.168.1.12')
[W 210516 18:14:44 __init__:203] atx-agent has something wrong, auto recovering
[I 210516 18:14:44 __init__:331] wait-for-device, time left(3.0s)
[I 210516 18:14:45 __init__:331] wait-for-device, time left(2.0s)
[I 210516 18:14:46 __init__:331] wait-for-device, time left(1.0s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\pycharm\Code\atxDemo2\venv\lib\site-packages\uiautomator2\__init__.py", line 1864, in connect
return connect_usb(addr)
File "D:\pycharm\Code\atxDemo2\venv\lib\site-packages\uiautomator2\__init__.py", line 1905, in connect_usb
return Device(serial)
File "D:\pycharm\Code\atxDemo2\venv\lib\site-packages\uiautomator2\__init__.py", line 242, in __init__
wlan_ip = self.wlan_ip
File "D:\pycharm\Code\atxDemo2\venv\lib\site-packages\uiautomator2\__init__.py", line 421, in wlan_ip
ip = self.http.get("/wlan/ip").text.strip()
File "D:\pycharm\Code\atxDemo2\venv\lib\site-packages\requests\sessions.py", line 555, in get
return self.request('GET', url, **kwargs)
File "D:\pycharm\Code\atxDemo2\venv\lib\site-packages\uiautomator2\__init__.py", line 208, in request
self.__client._prepare_atx_agent()
File "D:\pycharm\Code\atxDemo2\venv\lib\site-packages\uiautomator2\__init__.py", line 286, in _prepare_atx_agent
raise RuntimeError("USB device %s is offline" % self._serial)
RuntimeError: USB device 192.168.1.12 is offline
>>>
上面连接出现了错误,原因是有些手机系统上uiautomator2的 atx-agent 无法自动拉起,所以需要手动通过adb命令启动。执行如下 adb 命令:
# 1,通过USB连接电脑,开启远程ADB,下面指定的端口为 5555
D:\>adb devices
List of devices attached
D:\>adb tcpip 5555
restarting in TCP mode port: 5555
# 2,断开USB连接,连接WiFi
D:\>adb connect 192.168.1.12:5555
already connected to 192.168.1.12:5555
# 3,查看连接状态
D:\>adb devices
List of devices attached
192.168.1.12:5555 device
最后,再到Python交互窗口,执行以下命令:
>>> import uiautomator2 as u2
>>> d = u2.connect('192.168.1.12')
[W 210516 18:26:03 __init__:203] atx-agent has something wrong, auto recovering
[I 210516 18:26:03 __init__:331] wait-for-device, time left(3.0s)
[D 210516 18:26:03 __init__:287] device 192.168.1.12 is online
[I 210516 18:26:04 init:156] uiautomator2 version: 2.15.2
>>> d.info
[D 210516 18:26:10 __init__:630] kill process(ps): uiautomator
[D 210516 18:26:13 __init__:648] uiautomator-v2 is starting ... left: 40.0s
[D 210516 18:26:15 __init__:648] uiautomator-v2 is starting ... left: 38.7s
[I 210516 18:26:15 __init__:613] uiautomator back to normal
{'currentPackageName': 'com.sec.android.app.launcher', 'displayHeight': 1920, 'displayRotation': 0, 'displaySizeDpX': 360, 'displaySizeDpY': 640, 'displayWidth': 1080, 'productName': 'hel-2qec', 'screenOn': True, 'sdkInt': 26, 'naturalOrientation': True}
>>>
如果需要断开WiFi连接,可执行 adb 命令:
D:\>adb disconnect 192.168.1.12:5555
disconnected 192.168.1.12:5555
该方式可以不需要USB数据线就实现连接,但可能会因网络问题而出现不稳定的现象。