STF(SmartphoneTestFarm)是一个移动设备管理平台,可以对移动设备进行远程管理、调试、远程桌面监控等操作。
这个系统类似于目前很流行的云测服务,但是目前只适合内部系统使用,从设计之初就没有过多考虑多用户及数据安全性。
虽然网页上提供的设备很像模拟器,但是实际上都是真机,因此安装到设备上的应用流畅性以及运行环境的真实性可以得到保证。
请注意,即使直接从NPM安装了STF,也需要这些依赖项,因为它们不能包含在软件包中。
在MacOS上,可以使用brew安装大多数依赖项:
brewinstallrethinkdbgraphicsmagickzeromqprotobufyasmpkg-config但上述代码很可能执行失败,届时根据brew的提示进行操作,可能涉及从源码安装、缺失依赖安装、无权限处理等,最终耗时可能比较长。
官方推荐在Linux发行版上安装使用STF,开发团队的开发环境为CoreOS,因此使用Linux发行版可能搭建过程较为容易,生产体验可能较其他系统更好。
安装好前置依赖之后就比较简单了,这里通过npmjs安装STF,仅需一行代码(如果顺利的话):
npminstall-gstf静静等待安装完成,如果执行失败,届时根据提示进行操作,可能涉及从源码安装、缺失依赖安装、无权限处理等。
上述代码属于基本使用,建议将上述代码替换为如下代码:
除了本地用户之外,STF还提供管理员级别,增加了对某些功能的权限(例如预订和分区系统、释放占用的设备、用户和设备管理等)。相应的内置管理员用户信息如下:
名称:administrator电子邮件:administrator@fakedomain.com
STF还有另一个内置对象,是用户和设备第一次注册到STF数据库时所属的根标准组,其默认名称为Common。
可以通过设置以下环境变量来覆盖这些内置对象的默认值,然后通过stflocal(之前未运行过STF)或stfmigrate(之前已运行过STF)命令初始化STF数据库:
sudostflocal--public-ip
主机上USB接口有限,接普通的USBHUB会有供电不足的问题,如果用自供电的USBHUB也会有数据传输速率低延迟高的问题。
考虑过启动adb的WiFi连接模式,但传输的数据不够稳定,容易出现断开连接的情况。
最后发现adb可以进行远程连接,在STF服务器上远程连接其他设备上的adb服务,可以稳定扩张有限的USB接口,充分利用其他设备多余的USB接口。
首先需要在待连接的目标设备上运行adb服务(没有adb的话要装一个),端口号是5037,最好不要改端口号:
adbnodaemonserver-a-P5037之后在STF服务器上运行命令(记得要填入远程设备的IP地址):
运行成功后,STF服务器就可以连接到远程设备上的安卓手机了,但是无法读取到正在连接的状态,插上安卓手机后要等手机上的STFAPP完全启动才能正常操作,只影响刚插上的手机。
首先在主服务器上启动STF服务,按本文【2.STF基本搭建流程】执行即可。
之后在子服务器上启动STF服务,但不要指定到主服务的域名上。
进入源码文件夹执行命令:
npminstall如果npm执行失败,根据提示进行操作,可能涉及从源码安装、缺失依赖安装、无权限处理等。
如果是bower执行失败,很可能是GitHub上存储的部分仓库访问失败,大概率是需要给终端配置代理环境,需要在终端中执行:
如果还有某个bower的依赖安装失败了,那么很可能是这个依赖的GitHub仓库没了。
没错,bower是实时从GitHub上拉源码的,而且STF依赖的三方开源库还挺多的,所以万一有人删库跑路了,我们本地编译也会挂。
如果有,那么同步一下重新编译。如果没有,那就自己去找一个fork的仓库吧,GitHub或者Gitee都行,找到以后自己建个GitHub仓库更新一下本地的bower.json,再重新编译。
顺利安装所有依赖以后,需要先进行gulp构建,执行命令:
gulpclean&&gulpwebpack:buildglup构建完成后,执行npm命令(Mac上需要增加sudo):
前端入口js是res/app/app.js,各个构成模块如下:
我们看到/res/app下面是各个模块的前端代码。每个模块基本上都是由一个index.js、对应的controller.js、对应的pug、对应的css组成,这些模块组合在一起,就组合成了我们的看到的前端页面。如果需要增加自己开发的前端页面,需要将你的模板加入到其中去。
每一个模块的入口是他们各自的index.js。
在对应的index.js里面里面,定义了某个路由对应的pug模板以及controller。对应的pug模板就是前端要展示的页面,controller通过和后端通信,给pug提供展示的数据。
这块引用了很多/res/app/components/stf/下面对应的service。service会用到Websocket与服务端进行通信。
所以综上,如果要增加一个页面,需要在app.js,增加require(‘./xx’).name,需要增加xx目录下的index.js,xx-controller.js,xx.pug,以及在/res/app/components/stf目录下增加xx-service.js。
修改前端代码后需要执行命令:
gulpclean&&gulpwebpack:build另外STF内置汉化,可以在设置页面自行切换,也可在res/app/components/stf/language/language-service.js中替换默认语言:
后端代码都在stf/lib目录下,一般启动stf服务器用的是nodebin/stflocal,顺着bin/stf文件很轻易找到cli.js。这个js使用command.js定义了大量的node命令,这些命令又调用util/procutil.js创建大量进程。
具体进程可以看下openstf官方给出的这张图,虽然现在DeviceFarmer有做一些改动,但大致框架应该变化不大:
后端代码目录结构如下:
服务端处理信息流转有三个文件,cli/websocket/index.js、cli/triproxy/index.js、cli/processor/index.js。
db是数据操作文件,STF使用的数据库是rethinkdb,rethinkdb是以json方式存储数据的。
主要的逻辑分为db/api.js、db/index.js、db/setup.js、db/tables.js。
db的操作只需要修改db/tables.js与db/api.js即可,其它两个文件可以不用修改,db/api.js主要用于数据库增删查操作。
units是核心代码,根据其命名可得知其作用。
修改后端代码后需要先停止STF服务,然后执行命令:
sudonpmlink最后再启动STF服务。
STF本身是不支持iOS设备的,但是实际使用中也有iOS设备的需求,最好也要对iOS设备进行支持。
目前有尝试对iOS设备添加支持能力,虽然成功了,但没有达到Android的使用效果,流畅度和清晰度都不足。
STF使用的都是真机,需要摄像头的话也是用了真机的摄像头,对于一些用户想要进行扫描二维码、人脸识别、图像识别等测试时就捉襟见肘了。
可以尝试将图片、视频通过STF传输到真机上,模拟摄像头输入。最好是可以接入计算机的摄像头(如果有的话),将计算机的摄像头反向代理给STF连接的真机,不过考虑到带宽问题应该不好实现。
STF支持Chrome远程调试工具,可以调试设备上的H5页面,但是需要连接的话需要一个比较长的链路,不是特别方便。
如果可以内置H5调试工具,通过一个按钮或者一个面板开启,会方便很多。
STF目前可以读取真机的剪贴板,将最近一条复制的内容显示出来。但是无法读取计算机的剪贴板,不能将内容粘贴到连接的真机上,也不能达到在真机上复制直接在计算机上粘贴的能力。
希望可以打通真机和计算机的剪贴板,在真机上复制可以直接在计算机上粘贴,反过来也一样,这样才是一个顺畅的跨屏复制粘贴能力。
目前大多数设备上只能响应英文输入,即在计算机上使用键盘只能在真机上输入英文。
但我发现,Pixel设备弹出的输入法可以在切换到中文输入的情况下,响应计算机上的键盘输入,正常输出中文,AndroidStudio自带模拟器的输入法也可以输入中文。可能是谷歌输入法的能力,Pixel即AndroidStudio模拟器的输入法均为谷歌输入法,其他设备上均为国产输入法,可能在这方便稍有不足。
最好是STF将键盘输入拦截,参考appium的方式,将设备的输入能力由系统控制而不是受输入法限制。
目前STF虽然可以看到连接的真机的屏幕视频,但是听不到真机发出的声音,如果真机在浏览一些含有声音资源的音视频,那么用户无法听到声音,反而真机突然发出的声音可能会吓到设备管理员。
如果可以拦截真机的声音播放,考虑将STF作为一个虚拟的播放器,把声音传输到用户的计算机上。
STF设计初衷便是面向公司内部,它对所有用户的设想就是有一定可信赖的基础,在数据的安全性上具有天然的危险性,进程之间的所有内部通信都是不安全且未加密的。
要将STF二次开发并推向商业化,首先要解决的就是数据安全性问题。
STF实际上就是一个内部的云测平台,基于STF可以迅速开发出一个商业化的云测平台,只需要解决数据安全性问题、更改其中的用户管理系统、完善汉化能力,就能够作为一个简单的云测平台使用了。
STF支持自动化测试的能力,所以可以将STF自动化测试提供一个商业化的版本,很多APP需要进行兼容性测试,通过足够多的设备、品牌、版本可以达到更全面的覆盖密度。