众所周知,安卓单台设备的 UI 自动化测试已经比较完善了,有数不清的自动化框架或者工具。但是介绍多设备管理的内容并不多,当手里的手机多了之后,要做自动化测试平台,这块的东西又不得不碰。我是一位比较喜欢实践的人,和同事在一起开发过简单的多设备管理系统,也用过开源的,后来又自己开发过。前前后后大概经历了 4 个不同的版本。
+--------------+
| |
| atx-server |
| |
+--+-------+--++
| | |
| | +--------------------------+
+---+ +-------+ |
| | |
| | |
+-----------v----+ +------v---------+ +---v------------+
| Android | | Android | | Android |
| | | | | |
| +---------+ | +---------+ | +---------+
| |atx-agent| | |atx-agent| | |atx-agent|
| | | | | | | | |
+------+---------+ +------+---------+ +------+---------+
atx-agent
运行在手机的内部,为手机增加了远程控制,自动化的功能。atx-server
最重要的功能,是将atx-agent
汇总到一个网页上展示,并提供一个 API 可以获取所有设备的列表。
点击设备最右侧的那个眼睛图标,就可以进入远程控制界面。功能比较简单,但是基本功能够用了。
目前只试过 80 台设备,更多的设备应该也不成问题,不知道上限是多少,手机多的可以帮我测试下。
关于UI 自动化, uiautomator2这个项目只需要知道设备的 ip 就可以运行自动化了,包括安装运行,推送文件,各种功能都有。在这个项目之上外加一个 Jenkins 之类的运行脚本的服务,稍加处理就是一个自动化测试平台了。美滋滋
辛辛苦苦终于写完了,希望看文章的人多思考思考,笔者非常期待思维的碰撞,欢迎留言。
项目地址: https://github.com/openatx/atx-server
附上 cynic 的实践文章:atx 安卓集群管理 安装运行及自动化的实践
手动点赞
赞呀!后面抽空试用下~
相当赞
NB,在上家公司 OPENSTF 我都还没看完代码就匆匆的离职了。能读完 STF 的所有代码收获肯定不少吧。
厉害了
厉害了我的哥
厉害了...回头马上试用一下。
回头学习下,给大佬点赞
💯
厉害了,我的哥!
我最近也在想让 AppCrawler 绕过 appium 直接支持你的 atx-server。目前的需求还是以设备管理为主,把 adb 做成 service 就可以了。这样架构就可以简单了。基于这个基础,甚至都可以搞个众测设备的公有云服务了
哈哈,我又有时间折腾了
```Fetching https://golang.org/x/net/context?go-get=1
https fetch failed: Get https://golang.org/x/net/context?go-get=1: dial tcp 216.239.37.1:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
我***和不***都下载不下来,不知道咋回事
agent 是个 app 吗?怎么启动?
我选择了第三个,进行解锁操作,然后第二个设备解锁了,第三个没解锁
手动点赞
手动点赞
已使用,超赞👍 请大神收下我的膝盖
执行 go get -v github.com/openatx/atx-server 的过程中一直有下面的提示:
go\src\github.com\openatx\atx-server\database.go:12:2: no Go files in C:\Users\用户名\go\src\gopkg.in\gorethink\gorethink.v4
单独去 go get 只能取到 gorethink.v3;go get v4 的话会提示:
can't load package: package gopkg.in/gorethink/gorethink.v4: no Go files in C:\Users\用户名\go\src\gopkg.in\gorethink\gorethink.v4
@codeskyblue 请问为啥我的远程控制界面是一直都是灰的
手机是红米 4,版本是 MIUI9.2,安卓版本是 6.0.1,用的浏览器是 ubuntu 16.04 的 firefox。开了好像没什么日志,logcat 的这个不知道有没有用
1 EsService2 W loaded /system/lib/egl/libEGL_adreno200.so
1 EsService2 W loaded /system/lib/egl/libEGL_adreno200.so
2000 EsService I readResults: read results: 32, lastRequestId: 330
2000 I Kgd.KeyguardUpdateMonitor: mTimeTickBroadcastReceiver current state is mBootCompleted=true mDeviceProvisioned=true mPhoneState=0 Keyguard.isShowing = false Keyguard.isOccluded = false mScreenOn=true
2000 libEGL D loaded /system/lib/egl/libEGL_adreno200.so
已经使用,感谢大佬的分享,不过在使用的过程中,发现 web 端的手机屏幕截图刷新很慢哦
感谢楼主分享,我发现一个问题,
1、使用 N5 6.0 系统手机,一开始连接正常。监控页面也可以看到手机。当我关机再重启以后就无法再正常连接手机了。除非重新输入 python -m uiautomator2 init。得手动重新启动 atx-server 吗?
2、可以直接使用 adb connect ip 吗?就像 stf 那样直接远程连接?我发现连接显示成功,但设备都是 offline 呢
adb tcpip 5555
, 然后你就可以adb connect $IP
了感谢楼主回复。之前考虑的是如果做成公司级别的设备管理系统,手机都在大家手中。如果重启以后还需要 init 的话就有点不便了,估计就再也连不上了。最好可以开机自启就能重新连接。
如果可以默认的进行 adb connect ip,那么安装应用也会方便很多,现在只能支持 url 链接。
@codeskyblue 手机黑屏的话不能唤醒,stf 目前支持唤醒的,希望能把这个功能做进去。不然远程的话还要通知别人把屏幕打开。。
atx-agent 不能唤醒是因为用的 wlan,黑屏之后,wlan 断开了,无法跟手机继续通信了。(PS: 突然想到可以断开之后,直接再自动解锁屏幕,强制恢复 wlan。明天试试)
期待 iOS 的集群管理~~~~
现在执行了 python -m uiautomator2 init 手机添加不上去,加了电脑 IP+ 端口也不行,之前好好的,请问是什么问题呢
好厉害,最近在学 go,一定拜读您的代码。
atx-agent 端当 IP 发生变化时没法主动通知 atx-server 端。会造成设备离线无法管理。可否在 atx-agent 端做一个心跳。定时向 server 端报告信息.IP 变化时 server 端也换设备 IP。
atx-agent 运行在手机的内部,为手机增加了远程控制,自动化的功能。atx-server 最重要的功能,是将 atx-agent 汇总到一个网页上展示,并提供一个 API 可以获取所有设备的列表。----现在版本 atx-agent 自动化这块,就是网页端鼠标操作一台单独设备,然后该手机端会跟着执行吗?atx-server 没法让所有连接到的手机一起运行同一份脚本吗?看 git 上 atx-agent 的说明,同时对所有连接的手机执行命令,是要在终端里面进行操作?但似乎没有 atx 里那些找图的功能可以用呀?
超赞,什么时候把 logcat 这块写好?很需要
你说的那个 java 项目是 fork 的,大部分代码是https://github.com/xiaocong写的, 我的 java 不怎么好
不懂 go,但是感觉很强大~
安装成功后在本地的 localhost 页面,更多栏位没有出现眼睛的图标,是什么原因造成的呢
@codeskyblue ,请问一下再华为 P9 plus 上 下载安装微信,遇到错误,在 nexus 6p 下试验成功,会是什么原因?
d.app_install("http://dldir1.qq.com/weixin/android/weixin666android1300.apk"
)
13:21:54 id: 10
13:21:54 download initialing
13:21:55 download initialing
13:21:56 download 100%
13:21:56 http download error
Traceback (most recent call last):
File "", line 1, in
File "D:\Android\python36\lib\site-packages\uiautomator2_init.py", line 47
7, in app_install
return self._wait_install_finished(id, installing_callback)
File "D:\Android\python36\lib\site-packages\uiautomator2__init_.py", line 52
4, in _wait_install_finished
raise RuntimeError("error", jdata.get('error'))
RuntimeError: ('error', 'Get http://dldir1.qq.com/weixin/android/weixin666androi
d1300.apk: read udp 10.63.21.82:46756->221.12.1.227:53: i/o timeout')
你好,我的手机连接上 PC 运行是正常的,一旦拔出,就变成 offline 了。请问,这个东西需要同时 usb 连接到电脑上,还需要同在一个局域网内吗?
区别就是我这个专注自动化,顺便管理。
这种情况如何处理捏,红米 note2
我把 check_apk_installed 这个函数注释了,可能就是检查太快了,没安装完就检查了
目前在内网测试了一下,在服务器页面操作手机速度还可以,但在其他同事的页面上操作设备延迟就很高。光看手机运行是可以的,但是一操作就很卡了。stf 并没有类似问题,总体来说真心不错。
执行 go get -v github.com/openatx/atx-server
报错,错误如下:
C:\Users\Administrator>go get -v github.com/openatx/atx-server
github.com/openatx/atx-server
go\src\github.com\openatx\atx-server\httpserver.go:397:5: hbs.OnReconnect undefi
ned (type *heartbeat.Server has no field or method OnReconnect)
C:\Users\Administrator>python -m uiautomator2 init 10.0.1.1:8000
2018-05-08 14:26:59,427 - main.py:254 - INFO - atx-server addr 10.0.1.1:8000
2018-05-08 14:26:59,506 - main.py:269 - INFO - Detect pluged devices: ['980f
5397']
2018-05-08 14:26:59,507 - main.py:286 - INFO - Device(980f5397) initialing .
..
[Kminicap.so |################################| 13.2K / 13.2K
[?25h2018-05-08 14:27:09,736 - main.py:113 - INFO - install minicap
[Kminicap |################################| 357.9K / 357.9K
[?25h2018-05-08 14:27:22,467 - main.py:120 - INFO - install minitouch
[Kminitouch |################################| 29.5K / 29.5K
[?25h2018-05-08 14:27:27,442 - main.py:143 - INFO - app-uiautomator.apk(1.0
.13) installing ...
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\urllib3\connectionpool.py", line 601, in u
rlopen
chunked=chunked)
File "C:\Python36\lib\site-packages\urllib3\connectionpool.py", line 387, in _
make_request
six.raise_from(e, None)
File "", line 2, in raise_from
File "C:\Python36\lib\site-packages\urllib3\connectionpool.py", line 383, in _
make_request
httplib_response = conn.getresponse()
File "C:\Python36\lib\http\client.py", line 1331, in getresponse
response.begin()
File "C:\Python36\lib\http\client.py", line 297, in begin
version, status, reason = self._read_status()
File "C:\Python36\lib\http\client.py", line 266, in _read_status
raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\requests\adapters.py", line 440, in send
timeout=timeout
File "C:\Python36\lib\site-packages\urllib3\connectionpool.py", line 639, in u
rlopen
_stacktrace=sys.exc_info()[2])
File "C:\Python36\lib\site-packages\urllib3\util\retry.py", line 357, in incre
ment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Python36\lib\site-packages\urllib3\packages\six.py", line 685, in rer
aise
raise value.with_traceback(tb)
File "C:\Python36\lib\site-packages\urllib3\connectionpool.py", line 601, in u
rlopen
chunked=chunked)
File "C:\Python36\lib\site-packages\urllib3\connectionpool.py", line 387, in _
make_request
six.raise_from(e, None)
File "", line 2, in raise_from
File "C:\Python36\lib\site-packages\urllib3\connectionpool.py", line 383, in _
make_request
httplib_response = conn.getresponse()
File "C:\Python36\lib\http\client.py", line 1331, in getresponse
response.begin()
File "C:\Python36\lib\http\client.py", line 297, in begin
version, status, reason = self._read_status()
File "C:\Python36\lib\http\client.py", line 266, in _read_status
raise RemoteDisconnected("Remote end closed connection without"
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Re
mote end closed connection without response',))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python36\lib\runpy.py", line 193, in run_module_as_main
"main", mod_spec)
File "C:\Python36\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Python36\lib\site-packages\uiautomator2__main.py", line 352, in
odule>
main()
File "C:\Python36\lib\site-packages\uiautomator2__main.py", line 348, in ma
in
fire.Fire(MyFire)
File "C:\Python36\lib\site-packages\fire\core.py", line 127, in Fire
component_trace = _Fire(component, args, context, name)
File "C:\Python36\lib\site-packages\fire\core.py", line 366, in _Fire
component, remaining_args)
File "C:\Python36\lib\site-packages\fire\core.py", line 542, in _CallCallable
result = fn(*varargs, **kwargs)
File "C:\Python36\lib\site-packages\uiautomator2__main.py", line 273, in in
it
ignore_apk_check)
File "C:\Python36\lib\site-packages\uiautomator2__main.py", line 291, in _i
nit_with_serial
ins.install_uiautomator_apk(apk_version, reinstall)
File "C:\Python36\lib\site-packages\uiautomator2__main.py", line 144, in in
stall_uiautomator_apk
path = cache_download(app_url)
File "C:\Python36\lib\site-packages\uiautomator2__main_.py", line 73, in cac
he_download
r = requests.get(url, stream=True)
File "C:\Python36\lib\site-packages\requests\api.py", line 72, in get
return request('get', url, params=params, **kwargs)
File "C:\Python36\lib\site-packages\requests\api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Python36\lib\site-packages\requests\sessions.py", line 508, in reques
t
resp = self.send(prep, **send_kwargs)
File "C:\Python36\lib\site-packages\requests\sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "C:\Python36\lib\site-packages\requests\adapters.py", line 490, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected(
'Remote end closed connection without response',))
是直接在 git 下载下来 就可以直接运行了吗?还说需要配置?
use 和离线这个状态是根据什么来判断的?
目前管理服务器部署在 A 服务器上,多部手机装 atx 服务是在 B 电脑装的,如何快速把手机接入到 A 服务器的管理平台 (除了卸载服务用 A 服务器装以外),因为发现使用 IP+ 端口查看 info 信息 uuid 是一致的,是否只用在 A 服务器某文件写入相应信息就可以连接上 A 服务器管理平台呢?
准备实践下,想请教下楼主,atx-agent 如何解决国内各种定制手机的 apk 安装的限制? 比如 oppo、vivo 的帐号弹框,vivo 还有个烦人的模拟点击,小米的安全权限等等。
重启能否自动拉起 atx-agent 呢?
因为安卓手机有 bug,存在 uid leak 的情况,简单来说就是 apk 循环安装卸载,重复 10000 次,手机就没办法再安装 apk 了,需要卸载全部第三方 apk 后重启手机,这个 bug 报给 google,但明确表示 won't fix。
加油,暂时继续使用 openstf
求助,现在管理设备服务器在 imac 上,通过其他电脑访问设备管理页面,不能操作设备,看报错,应该是无法连接手机设备。
remote.js?t=1526889597:570 WebSocket connection to 'ws://192.168.2.26:7912/minicap' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
有什么解决办法吗?
atx-agent 是个 apk 么? 还是一个 so? 运行在 andoroid 上会不会被杀(比如 oppo vivo 有些 top50 的手机后台定期会清理内存,加入白名单都不行)?
这个项目里的 Advanced usage 不是很懂,大佬可以简单说明一下吗?
win7 安装 atx 报错如下:
F:\Go\src>go get -v github.com/openatx/atx-server
github.com/openatx/atx-server (download)
com\openatx\atx-server
Cloning into 'F:\golang\go\src\github.com\openatx\atx-server'...
fatal: unable to access 'https://github.com/openatx/atx-server/:' error:1407742E
:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
package github.com/openatx/atx-server: exit status 128
体验了一下,貌似手机切换网络或断网,自动重连后,设备可以正常显示,但无法在 web 页面对手机进行远程控制操作
请问能否在 uiautomator.apk 里面添加把 axt-agent 注册到 atx-server 的功能,这样不用每次连电脑注册。
所有设备连接在一个 wifi 下,80 台手机的话是否有带宽不足的问题,能否数据线 + 有限网络实现,求教
大佬,其实这样就完全可以知道局域网内哪些 ip 的手机安装了 ATX 或者 ui2 客户端,然后测试局域网内的多台有 ATX 的设备哇,可以提供一个方法获取这些有用的 ip,或者默认直接就测试这些 ip 哇,感觉可行,比较省事,省去了测不了多台手机的尴尬
页面是这样,功能用不了,求指点
我查了下是这样说的:golang 不允许循环导包,如果检测到 import cycle,会在编译时报错,通常 import cycle 是因为设计错误或包的规划问题。
可是我不知道怎么解决,有遇到的嘛
请问以后有可能支持 iOS 吗?
重启后可以通过连接 USB 线然后执行下面命令来重启服务
adb shell /data/local/tmp/atx-agent server --server 192.168.101.209:8000 -d
是的 需要手动执行, 或者找个 root 的 android 设备写个能执行 adb shell 命令的 apk,直接在 apk 里执行 shell 脚本
楼主,USB 连接的设备能直接控制吗?直接连在台式电脑上
请问为什么识别不了参数呢
楼主,非常棒,准备学习下源码
failed to authenticate to localhost:6174 https://github.com/codeskyblue/adbkit/tree/fix-adb40 在这里已经解决了么?
连接后貌似还是会提示 failed
一起来发展这个项目,建议先组个群