STF平台搭建及二次開發


STF平台搭建及二次開發

來源 https://51posts.com/2021/12/16/01/50/22/11481/

 

1. STF簡要功能介紹

1.1 什么是STF?

STF平台搭建及二次開發

STF(Smartphone Test Farm)是一個移動設備管理平台,可以對移動設備進行遠程管理、調試、遠程桌面監控等操作。

這個系統類似於目前很流行的雲測服務,但是目前只適合內部系統使用,從設計之初就沒有過多考慮多用戶及數據安全性。

雖然網頁上提供的設備很像模擬器,但是實際上都是真機,因此安裝到設備上的應用流暢性以及運行環境的真實性可以得到保證。

STF平台搭建及二次開發

STF代碼開源,原始團隊openstf已解散,原項目openstf/stf不再維護。原始團隊推薦了一個fork項目DeviceFarmer/stf,目前在緩慢迭代中,本文基於DeviceFarmer/stf的3.6.1版本撰寫。

1.2 STF支持的功能有什么?

  • 通過瀏覽器遠程控制任何設備
    • 實時屏幕視圖
      • 刷新速度可以達到30-40 FPS,具體取決於規格和Android版本。有關更多信息,請參見minicap
      • 支持屏幕旋轉
    • 支持使用自己的鍵盤輸入文字
      • 支持中繼鍵
      • 復制和粘貼支持(盡管在較舊的設備上可能有點挑剔,但您可能需要長按並手動選擇粘貼)
      • 不幸的是,可能不適用於非拉丁語言
    • 通過minitouch在觸摸屏上提供多點觸摸支持,Alt在拖動時按住可以在常規屏幕上支持兩根手指捏/旋轉/縮放手勢
    • 拖放安裝和啟動.apk文件
    • 通過minirev反向端口轉發
      • 即使設備不在同一網絡上,也可以直接從設備訪問本地服務器
    • 在任何瀏覽器中輕松打開網站
      • 實時檢測已安裝的瀏覽器,並顯示為可選選項
      • 如果用戶選擇默認瀏覽器,則會自動檢測到
    • 執行shell命令並查看實時輸出
    • 顯示和過濾設備日志
    • 可以使用adb connect連接遠程設備
      • adb可以在本地運行任何命令,包括shell訪問
      • Android Studio和其他IDE支持,在瀏覽器上觀看設備屏幕的同時調試您的應用程序
      • 支持Chrome遠程調試工具
    • 提供文件資源管理器以訪問設備文件系統
    • VNC實驗支持(正在進行中)
  • 監控您的設備清單
    • 查看哪些設備已連接,離線/不可用(表明USB連接弱),未授權或已拔出
    • 查看誰在使用設備
    • 通過電話號碼,IMEI,ICCID,Android版本,運營商,產品名稱,組名稱和/或許多其他屬性來搜索設備,並具有簡單但功能強大的查詢
    • 在需要物理定位的設備上顯示帶有標識信息的亮紅色屏幕
    • 跟蹤電池電量和健康狀況
    • 基本的Play商店帳戶管理
      • 顯示,刪除和添加新帳戶(添加可能無法在所有設備上進行)
    • 顯示硬件規格
  • 簡單的 REST API

2. STF基本搭建流程

2.1 STF的前置依賴

  • 需要Node.js 8.x (某些依賴項不支持較新的版本)
  • adb正確設置(安卓調試橋)
  • RethinkDB > = 2.2(數據庫)
  • GraphicsMagick(用於調整屏幕截圖的大小)
  • 安裝了ZeroMQ庫
  • 已安裝protobuf庫
  • 安裝了yasm(用於編譯嵌入式libjpeg-turbo)
  • pkg-config

請注意,即使直接從NPM安裝了STF,也需要這些依賴項,因為它們不能包含在軟件包中。

在Mac OS上,可以使用brew安裝大多數依賴項:

brew install rethinkdb graphicsmagick zeromq protobuf yasm pkg-config

但上述代碼很可能執行失敗,屆時根據brew的提示進行操作,可能涉及從源碼安裝、缺失依賴安裝、無權限處理等,最終耗時可能比較長。

官方推薦在Linux發行版上安裝使用STF,開發團隊的開發環境為CoreOS,因此使用Linux發行版可能搭建過程較為容易,生產體驗可能較其他系統更好。

2.2 npm簡易安裝STF

安裝好前置依賴之后就比較簡單了,這里通過npmjs安裝STF,僅需一行代碼(如果順利的話):

npm install -g stf

靜靜等待安裝完成,如果執行失敗,屆時根據提示進行操作,可能涉及從源碼安裝、缺失依賴安裝、無權限處理等。

2.3 運行及登錄方式

2.3.1 STF基本運行

安裝完成后,先開一個窗口運行rethinkdb,再開一個窗口運行stf,之后就可以通過 http://localhost:7100/ 訪問stf平台了,具體代碼如下:

rethinkdb

stf local

【注意】要分兩個窗口分別運行,先運行 rethinkdb ,再運行 stf local 。
如果 RethinkDB 啟動花費了很長時間,可能是遇到了 rethinkdb/rethinkdb#4600 或 rethinkdb/rethinkdb#6047 問題。通常發生在 macOS Sierra 上,需要先運行 scutil --get HostName 以檢查 HostName 變量是否未設置,RethinkDB 需要它為生成服務器名稱。如果它是空的,執行 sudo scutil --set HostName $(hostname) 可以解決該問題。

上述代碼屬於基本使用,建議將上述代碼替換為如下代碼:

rethinkdb --bind all --cache-size 8192 --http-port 8090

stf local --public-ip <ip_here> --port <port_here> --allow-remote

執行完成后,你可以通過 http://<ip_here>:<port_here>/ 訪問stf平台。如果將<port_here>設置為80,則無需輸入端口號即 http://<ip_here> ,另外還可以將<ip_here>設置為域名。

2.3.2 mock登錄方式

STF默認以mock登錄方式運行,無需特別指定,2.3.1中的代碼即為mock登錄方式運行的。

除了本地用戶之外,STF 還提供管理員級別,增加了對某些功能的權限(例如預訂和分區系統、釋放占用的設備、用戶和設備管理等)。相應的內置管理員用戶信息如下:

名稱: administrator
電子郵件: administrator@fakedomain.com

STF還有另一個內置對象,是用戶和設備第一次注冊到STF數據庫時所屬的根標准組,其默認名稱為 Common。

可以通過設置以下環境變量來覆蓋這些內置對象的默認值,然后通過stf local(之前未運行過STF)或stf migrate(之前已運行過STF)命令初始化 STF 數據庫:

  • 根標准組名稱: STF_ROOT_GROUP_NAME
  • 管理員用戶名: STF_ADMIN_NAME
  • 管理員用戶郵箱: STF_ADMIN_EMAIL

2.3.3 ldap登錄方式

另外STF還可以支持LDAP登錄,可以接入公司的LDAP服務,部分信息需要咨詢公司的LDAP系統負責人,以LDAP登錄方式啟動的命令如下:

sudo stf local --public-ip <ip_here> --port <port_here> --auth-type ldap --auth-options '["--app-url","<app_url>","--ldap-url","<ldap_url>","--ldap-search-dn","<ldap_dn>","--ldap-search-class","<ldap_class>","--ldap-search-field","<ldap_id>","--ldap-username-field","<ldap_name>"]' --allow-remote

除了之前需要的–public-ip和–port,還有比較多的新增參數,我們一個個分析:

  • --auth-type ldap:指定ldap登錄方式
  • --auth-options:ldap登錄需要的參數
    • "--app-url","<app_url>":STF的訪問url,應填寫http://<ip_here>:<port_here>/,用於因重置密碼等邏輯跳轉ldap系統后返回STF
    • "--ldap-url","<ldap_url>":ldap系統url,通常為ldaps://ldap.<xxx>.com/,請詢問ldap系統負責人
    • "--ldap-search-dn","<ldap_dn>":ldap系統dn信息,例如dc=xxx,dc=com,請詢問ldap系統負責人
    • "--ldap-search-class","<ldap_class>":ldap用戶存儲表名,請詢問ldap系統負責人
    • "--ldap-search-field","<ldap_id>":ldap用戶標識字段名,匹配輸入的username,類似賬號,請詢問ldap系統負責人
    • "--ldap-username-field","<ldap_name>":ldap用戶名稱顯示字段名,匹配顯示的用戶名稱displayName,類似昵稱,請詢問ldap系統負責人

3. STF的分布式部署

3.1 ADB遠程連接其他計算機上的Android設備

主機上USB接口有限,接普通的USB HUB會有供電不足的問題,如果用自供電的USB HUB也會有數據傳輸速率低延遲高的問題。

考慮過啟動adb的WiFi連接模式,但傳輸的數據不夠穩定,容易出現斷開連接的情況。

最后發現adb可以進行遠程連接,在STF服務器上遠程連接其他設備上的adb服務,可以穩定擴張有限的USB接口,充分利用其他設備多余的USB接口。

首先需要在待連接的目標設備上運行adb服務(沒有adb的話要裝一個),端口號是5037,最好不要改端口號:

adb nodaemon server -a -P 5037

之后在STF服務器上運行命令(記得要填入遠程設備的IP地址):

stf provider --name <服務器名稱> --min-port 7400 --max-port 7700 --connect-sub tcp://127.0.0.1:7114 --connect-push tcp://127.0.0.1:7116 --group-timeout 900 --public-ip <ip_here> --storage-url http://<ip_here>:<port_here>/ --adb-host <遠程設備ip地址> --adb-port 5037 --vnc-initial-size 600x800 --mute-master never --allow-remote

服務器名稱可隨意取,http://<ip_here>:<port_here>/即STF服務器訪問url,遠程設備ip地址是充當USB HUB的計算機ip地址。

運行成功后,STF服務器就可以連接到遠程設備上的安卓手機了,但是無法讀取到正在連接的狀態,插上安卓手機后要等手機上的STF APP完全啟動才能正常操作,只影響剛插上的手機。

3.2 多台STF服務器遠程連接

STF支持分布式部署,具體是否需要相同的版本和相同的登錄方式還未實踐確定。

首先在主服務器上啟動STF服務,按本文【2. STF基本搭建流程】執行即可。

之后在子服務器上啟動STF服務,但不要指定到主服務的域名上。

最后在子服務器上執行命令,其中http://<ip_here>:<port_here>/為主服務器訪問url:

stf provider --name <設備名> --min-port 7400 --max-port 7700 --connect-sub tcp://<ip_here>:7114 --connect-push tcp://<ip_here>:7116 --group-timeout 20000 --public-ip <ip_here> --storage-url http://<ip_here>:<port_here>/ --vnc-initial-size 600x800 --allow-remote

4. STF二次開發入門

4.1 本地編譯STF

要二次開發STF,也需要先了解安裝即運行,參考本文【2. STF基本搭建流程】,本節內容替換【2.2 npm簡易安裝STF】,則是一個完整的本地編譯運行過程。

首先按【2.1 STF的前置依賴】完成前置依賴的配置,隨后需要下載STF的源碼,參考項目DeviceFarmer/stf

進入源碼文件夾執行命令:

npm install

如果npm執行失敗,根據提示進行操作,可能涉及從源碼安裝、缺失依賴安裝、無權限處理等。

npm執行完成后會自動執行bower相關命令,需要獲取相關的bower依賴。

如果是bower執行失敗,很可能是GitHub上存儲的部分倉庫訪問失敗,大概率是需要給終端配置代理環境,需要在終端中執行:

export http_proxy=<http_proxy>
export https_proxy=<https_proxy>

需要一個代理環境,<http_proxy>和<https_proxy>可以是一樣的,配置好代理之后,需要重新執行npm命令。

如果還有某個bower的依賴安裝失敗了,那么很可能是這個依賴的GitHub倉庫沒了。

沒錯,bower是實時從GitHub上拉源碼的,而且STF依賴的三方開源庫還挺多的,所以萬一有人刪庫跑路了,我們本地編譯也會掛。

這時候看看報錯是哪個庫沒了,然后看看DeviceFarmer最新的master分支上的bower.json文件和本地對比一下,看看那個庫有沒有更新一個新的GitHub倉庫來源。

如果有,那么同步一下重新編譯。如果沒有,那就自己去找一個fork的倉庫吧,GitHub或者Gitee都行,找到以后自己建個GitHub倉庫更新一下本地的bower.json,再重新編譯。

順利安裝所有依賴以后,需要先進行gulp構建,執行命令:

gulp clean && gulp webpack:build

glup構建完成后,執行npm命令(Mac上需要增加sudo):

sudo npm link

最后就可以執行stf的啟動命令了,參考【2.3 運行及登錄方式】。

4.2 前端二次開發簡介

STF涉及的相關知識點有:

  • webpack
  • gulp
  • angularjs
  • bower
  • Promise
  • websocket
  • protobuf

前端入口js是res/app/app.js,各個構成模塊如下:

angular.module('app', [
  'ngRoute',
  'ngTouch',
  require('gettext').name,
  require('angular-hotkeys').name,
  require('./layout').name,
  require('./device-list').name,
  require('./group-list').name,
  require('./control-panes').name,
  require('./menu').name,
  require('./settings').name,
  require('./docs').name,
  require('./user').name,
  require('./../common/lang').name,
  require('stf/standalone').name,
  require('./group-list').name
])

前端相關的代碼都在res文件夾下,目錄結構如下:

STF平台搭建及二次開發

我們看到/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。

修改前端代碼后需要執行命令:

gulp clean && gulp webpack:build

另外STF內置漢化,可以在設置頁面自行切換,也可在res/app/components/stf/language/language-service.js中替換默認語言:

    LanguageService.settingKey = 'selectedLanguage'
    LanguageService.supportedLanguages = supportedLanguages
    LanguageService.defaultLanguage = 'zh_CN'
    LanguageService.detectedLanguage =
      onlySupported(detectLanguage(), LanguageService.defaultLanguage)

目前STF對多語言的支持還不是特別完善,可以參考stf#translating,完善一下STF的多語言支持。

4.3 后端二次開發簡介

后端代碼都在stf/lib目錄下,一般啟動stf服務器用的是node bin/stf local,順着bin/stf文件很輕易找到cli.js。這個js使用command.js定義了大量的node命令,這些命令又調用util/procutil.js創建大量進程。

具體進程可以看下openstf官方給出的這張圖,雖然現在DeviceFarmer有做一些改動,但大致框架應該變化不大:

STF平台搭建及二次開發

后端代碼目錄結構如下:

STF平台搭建及二次開發

服務端處理信息流轉有三個文件,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服務,然后執行命令:

sudo npm link

最后再啟動STF服務。

5. STF后續發展之路

5.1 功能擴展

5.1.1 iOS支持

STF本身是不支持iOS設備的,但是實際使用中也有iOS設備的需求,最好也要對iOS設備進行支持。

DeviceFarmer/stf將支持iOS設備作為了長期目標,看起來是無法在短時間內實現的。

目前有嘗試對iOS設備添加支持能力,雖然成功了,但沒有達到Android的使用效果,流暢度和清晰度都不足。

5.1.2 攝像頭模擬

STF使用的都是真機,需要攝像頭的話也是用了真機的攝像頭,對於一些用戶想要進行掃描二維碼、人臉識別、圖像識別等測試時就捉襟見肘了。

可以嘗試將圖片、視頻通過STF傳輸到真機上,模擬攝像頭輸入。最好是可以接入計算機的攝像頭(如果有的話),將計算機的攝像頭反向代理給STF連接的真機,不過考慮到帶寬問題應該不好實現。

5.1.3 集成H5調試

STF支持Chrome遠程調試工具,可以調試設備上的H5頁面,但是需要連接的話需要一個比較長的鏈路,不是特別方便。

如果可以內置H5調試工具,通過一個按鈕或者一個面板開啟,會方便很多。

5.1.4 跨屏復制粘貼

STF目前可以讀取真機的剪貼板,將最近一條復制的內容顯示出來。但是無法讀取計算機的剪貼板,不能將內容粘貼到連接的真機上,也不能達到在真機上復制直接在計算機上粘貼的能力。

希望可以打通真機和計算機的剪貼板,在真機上復制可以直接在計算機上粘貼,反過來也一樣,這樣才是一個順暢的跨屏復制粘貼能力。

5.2 優化改進

5.2.1 觸屏流暢性

由於設備帶寬有限,錄屏 -> STF -> 計算機鏈路上需要花費一些時間,導致觸屏會有一點點延遲,錄屏的質量越高延遲越高,設備越多反應越慢,STF刷新速度基本上處於30-40 FPS甚至會更低一些。

Genymobile/scrcpy有相應的解決方案,直接通過反射調用安卓的SurfaceControl私有API,把屏幕傳給MediaCodec,由系統去做錄屏,最終編碼成H264,通過websocket發送給前端的video做展示。可能刷新速度可以達到60 FPS,並且流量能通過編碼器的碼率控制,由於視頻的壓縮方式優勢視頻流能極大的減少了帶寬,也不用考慮帶寬過大的問題。

5.2.2 中文輸入

目前大多數設備上只能響應英文輸入,即在計算機上使用鍵盤只能在真機上輸入英文。

但我發現,Pixel設備彈出的輸入法可以在切換到中文輸入的情況下,響應計算機上的鍵盤輸入,正常輸出中文,Android Studio自帶模擬器的輸入法也可以輸入中文。可能是谷歌輸入法的能力,Pixel即Android Studio模擬器的輸入法均為谷歌輸入法,其他設備上均為國產輸入法,可能在這方便稍有不足。

最好是STF將鍵盤輸入攔截,參考appium的方式,將設備的輸入能力由系統控制而不是受輸入法限制。

5.2.3 音頻傳輸

目前STF雖然可以看到連接的真機的屏幕視頻,但是聽不到真機發出的聲音,如果真機在瀏覽一些含有聲音資源的音視頻,那么用戶無法聽到聲音,反而真機突然發出的聲音可能會嚇到設備管理員。

如果可以攔截真機的聲音播放,考慮將STF作為一個虛擬的播放器,把聲音傳輸到用戶的計算機上。

5.3 商業化

5.3.1 數據安全性

STF設計初衷便是面向公司內部,它對所有用戶的設想就是有一定可信賴的基礎,在數據的安全性上具有天然的危險性,進程之間的所有內部通信都是不安全且未加密的。

要將STF二次開發並推向商業化,首先要解決的就是數據安全性問題。

5.3.2 雲測平台

STF實際上就是一個內部的雲測平台,基於STF可以迅速開發出一個商業化的雲測平台,只需要解決數據安全性問題、更改其中的用戶管理系統、完善漢化能力,就能夠作為一個簡單的雲測平台使用了。

5.3.3 自動化測試

STF支持自動化測試的能力,所以可以將STF自動化測試提供一個商業化的版本,很多APP需要進行兼容性測試,通過足夠多的設備、品牌、版本可以達到更全面的覆蓋密度。

 

================= End

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM