iOS自動(dòng)化測(cè)試驅(qū)動(dòng)工具探索

image

本文主要介紹了字節(jié) iOS 自動(dòng)化測(cè)試驅(qū)動(dòng)工具的探索過(guò)程及實(shí)現(xiàn)原理(火山引擎MARS)

作者:字節(jié)跳動(dòng)終端技術(shù)——陳友輝

一皮钠、背景

隨著業(yè)務(wù)的擴(kuò)張人柿,單個(gè) App 的功能越來(lái)越多哀托,工程復(fù)雜度越來(lái)越高,每天MR可達(dá)上百次瞳筏,代碼變更可達(dá)上千處卓缰,航母級(jí)的 App 在這一點(diǎn)上更為嚴(yán)重。如何在頻繁的代碼變更中保障App質(zhì)量掌挚,成了各個(gè)業(yè)務(wù)的痛點(diǎn)雨席。靠傳統(tǒng)的人工測(cè)試已無(wú)法滿足各業(yè)務(wù)的需求吠式,我們需要將更多的測(cè)試場(chǎng)景自動(dòng)化陡厘。

自動(dòng)化測(cè)試需要將人工交互行為變成自動(dòng)化的原子操作。比如應(yīng)用安裝卸載特占、屏幕點(diǎn)拖拽及縮放糙置、實(shí)體按鍵點(diǎn)擊、設(shè)備信息獲取摩钙、應(yīng)用啟停等等罢低。這就需要一款工具來(lái)驅(qū)動(dòng) iOS 設(shè)備完成以上操作。這篇文章主要介紹字節(jié) iOS 自動(dòng)化測(cè)試驅(qū)動(dòng)工具 bdc 的探索過(guò)程及實(shí)現(xiàn)原理胖笛。
image

二网持、功能介紹

在介紹 bdc 的探索過(guò)程及實(shí)現(xiàn)原理之前,先介紹一下 bdc 的能力:
image

三长踊、探索歷程

早期方案

在字節(jié)開(kāi)始大規(guī)模建設(shè)自動(dòng)化建設(shè)時(shí)功舀,Android 已經(jīng)有較為完善的解決方案,包括其生態(tài)自帶的驅(qū)動(dòng)工具 adb 及開(kāi)源的云真機(jī)管理平臺(tái) STF身弊。但 iOS 在這方面相對(duì)滯后辟汰,主要是 iOS 缺少一款類似 adb 功能齊全且穩(wěn)定的驅(qū)動(dòng)工具。

早期 iOS 采用了 Facebook 開(kāi)源的方案阱佛,F(xiàn)acebook 在驅(qū)動(dòng)工具方面先后開(kāi)源了 wda 與 idb帖汞,wda 支持 UI 交互操作,idb 支持應(yīng)用管理凑术,這在一定程度上滿足了我們的需求翩蘸,基于這套方案,搭建了第一個(gè)版本的自動(dòng)化測(cè)試機(jī)架淮逊。

image

早期的機(jī)架也很簡(jiǎn)單催首,機(jī)器的規(guī)模也不大
image

經(jīng)過(guò)一段時(shí)間的實(shí)踐隔披,我們遇到了以下幾個(gè)問(wèn)題

  • wda 部分接口執(zhí)行耗時(shí)較長(zhǎng)欣孤,效率低下叙甸,無(wú)法滿足高頻率調(diào)度的需求
  • idb 很多命令只支持模擬器番官,對(duì)真機(jī)不夠友好,無(wú)法滿足我們的功能擴(kuò)展
  • 命令執(zhí)行失敗率高舶治,工具穩(wěn)定性差分井,且出問(wèn)題后難以排查
  • 整套流程強(qiáng)依賴 Xcode 環(huán)境,規(guī)募叽化杂抽、自動(dòng)化部署成本高,無(wú)法應(yīng)對(duì)上千臺(tái)手機(jī)的部署

工具改良

UI 交互改造

為了解決上述問(wèn)題韩脏,我們結(jié)合 wda 的實(shí)現(xiàn)思路缩麸,實(shí)現(xiàn)了一個(gè)更高效穩(wěn)定的 XCTest 工具。我們對(duì) XCTest 相關(guān)的接口進(jìn)行了review赡矢,并找到了XCTest 實(shí)現(xiàn)跨進(jìn)程調(diào)用最底層的接口杭朱。通過(guò)這些接口,可以直接調(diào)用 testmanagerd 進(jìn)程吹散。隨后基于這些底層接口封裝了一套新的接口弧械,可以實(shí)現(xiàn)屏幕的點(diǎn)拖拽、實(shí)體按鍵點(diǎn)擊空民、文本輸入等操作刃唐。相比 wda,在執(zhí)行速度和穩(wěn)定性上獲得大幅提升界轩。

testmanagerd 進(jìn)程是一個(gè)開(kāi)發(fā)者守護(hù)進(jìn)程画饥,在 iOS 設(shè)備開(kāi)啟開(kāi)發(fā)者模式后,testmanagerd 進(jìn)程的鏡像會(huì)被掛載到 iOS 設(shè)備系統(tǒng)的 Developer 目錄浊猾,并被 launchd 進(jìn)程啟動(dòng)抖甘。XCTest 使用蘋果自帶的 XPC 機(jī)制與 testmanagerd 進(jìn)行通信,利用 NSXPCConnection葫慎,只需知道服務(wù)的 id 即可建立通信衔彻,testmanagerd 服務(wù)的 id 可在其鏡像文件里找到。鏡像的路徑位于:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

解壓鏡像后偷办,可在 Library/LaunchDeamons 目錄下找到名為 com.apple.testmanagerd 的 plist 文件艰额,打開(kāi)后可以看到其 id 為 com.apple.testmanagerd(iOS14 后 id 有所變動(dòng))

image

設(shè)備交互工具

搞定 UI 交互后,接下來(lái)就需要找到能完美支持設(shè)備管理椒涯、應(yīng)用管理悴晰、沙盒文件管理的方案。一開(kāi)始我們也是想基于 idb 進(jìn)行優(yōu)化逐工,但隨后發(fā)現(xiàn) idb 內(nèi)部使用了大量的 api铡溪,這些 api 絕大部分缺少文檔,優(yōu)化成本較高泪喊,且這些私有 api 會(huì)隨著 Xcode 版本的變動(dòng)而更新棕硫,維護(hù)會(huì)很麻煩。所以放棄了 idb 轉(zhuǎn)而尋找其他替代方案袒啼。

這時(shí)我們發(fā)現(xiàn)了另一個(gè)開(kāi)源實(shí)現(xiàn) libimobiledevice哈扮,libimobiledevice 支持通過(guò) USB 的方式與 iOS 設(shè)備進(jìn)行通信,且支持應(yīng)用安裝卸載蚓再、設(shè)備信息獲取滑肉、沙盒文件操作等功能。libimobiledevice 在使用體驗(yàn)上摘仅,操作簡(jiǎn)單靶庙,功能穩(wěn)定。但缺點(diǎn)是功能有限娃属,不能完全符合我們的訴求六荒,接下來(lái)我們對(duì) libimobiledevice 的實(shí)現(xiàn)原理進(jìn)行了探究。

基于 USB 與 iOS 設(shè)備通信

蘋果自身有一些 Mac App 需要通過(guò) USB 跟 iOS 設(shè)備進(jìn)行通信矾端,比如 iTunes掏击、XCode 及其套件等等。雙端通信需要基于一定的協(xié)議秩铆,通過(guò)USB通信需要使用USB協(xié)議砚亭,但USB協(xié)議具有一定的局限性,直接使用成本較高殴玛。所以蘋果在USB協(xié)議的基礎(chǔ)上支持了TCP通信的能力捅膘,以此減小使用成本。

蘋果通過(guò) usbmuxd 來(lái)提供基于 USB 實(shí)現(xiàn) TCP 通信的能力族阅。usbmuxd是一個(gè)守護(hù)進(jìn)程篓跛,它在 USB協(xié)議上實(shí)現(xiàn)了多路 TCP 連接,可以讓應(yīng)用層無(wú)感知的基于 USB 通道進(jìn)行 TCP 通信坦刀。

macOS 上的 usbmuxd 配置文件位于/Library/Apple/System/Library/LaunchDaemons愧沟,打開(kāi)后如下:

image

usbmuxd 的配置文件記錄了加載屬性、服務(wù)名稱鲤遥、可執(zhí)行文件路徑沐寺、socket 屬性等信息。從上面的配置文件可以看到盖奈,usbmuxd 創(chuàng)建了一個(gè) Unix 域的 socket混坞。這個(gè) socket 主要用于跟上層應(yīng)用建立連接,實(shí)現(xiàn)跨進(jìn)程通信【吭校基于 usbmuxd 進(jìn)行網(wǎng)絡(luò)通信的流程如下:
image

發(fā)現(xiàn)iOS設(shè)備系統(tǒng)服務(wù)并完成調(diào)用

從上述 usbmuxd 的通信流程可知啥酱,想要跟iOS設(shè)備中的服務(wù)進(jìn)行通信,只需要知道具體服務(wù)的端口即可厨诸。那么服務(wù)端口該如何獲认庖蟆?一般有兩種方式微酬,一種是直接hardcode绘趋,另一種是動(dòng)態(tài)獲取。iOS設(shè)備內(nèi)部的服務(wù)眾多颗管,如果全部 hardcode陷遮,其維護(hù)成本較高,且安全性及穩(wěn)定性較低垦江。如果是動(dòng)態(tài)獲取帽馋,那么獲取的方式將成為另一個(gè)問(wèn)題,因?yàn)閯?dòng)態(tài)獲取本身也需要通信疫粥。

蘋果則采用了兩者結(jié)合的方式茬斧。蘋果在iOS系統(tǒng)內(nèi)部增加了一個(gè) lockdownd 的守護(hù)進(jìn)程,這個(gè)守護(hù)進(jìn)程以 root 特權(quán)運(yùn)行梗逮,具有訪問(wèn) iOS 系統(tǒng)信息的能力项秉,且運(yùn)行在固定的端口。lockdownd 的配置文件如下慷彤,其路徑位于 iOS 系統(tǒng)的/System/Library/LaunchDaemons/目錄娄蔼。

image

由此可以看出,lockdownd 分別支持 Unix 域的 socket 與非 Unix 域的 socket底哗,對(duì)于非 Unix 域的socket岁诉,其監(jiān)聽(tīng)的端口固定在62078

當(dāng) PC 端想要跟 iOS 設(shè)備中的某個(gè)服務(wù)進(jìn)行通信時(shí)跋选,先通過(guò) lockdownd 查找對(duì)應(yīng)服務(wù)的端口涕癣,然后再跟對(duì)應(yīng)的服務(wù)建立 socket 連接,其流程如下:
image

libimobiledevice 就是利用以上流程對(duì) iOS 設(shè)備中的服務(wù)進(jìn)行了調(diào)用前标,比如在操作沙盒文件時(shí)坠韩,就是調(diào)用了 iOS 設(shè)備中的 afc、house_arrest 服務(wù)炼列。

服務(wù)類型

搞清楚了調(diào)用流程只搁,那么 iOS 設(shè)備中都有哪些服務(wù)呢?iOS 系統(tǒng)服務(wù)主要分為兩類:一類是debug相關(guān)服務(wù)俭尖,打開(kāi)開(kāi)發(fā)者選項(xiàng)后才具備相應(yīng)服務(wù)氢惋。另一類是非 debug 服務(wù)洞翩,默認(rèn)都具備。

debug 相關(guān)服務(wù)的配置文件及可執(zhí)行文件都被打包放在了 Xcode 中焰望,位于/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/目錄骚亿,當(dāng) iOS 設(shè)備連接 Xcode 時(shí),Xcode 會(huì)自動(dòng)將此目錄下對(duì)應(yīng)的DeveloperDiskImage掛載到 iOS 系統(tǒng)中柿估。其包含的服務(wù)如下:

image

上述提到的 testmanagerd 就位于其中循未。

非debug服務(wù)位于iOS系統(tǒng)的/System/Library/LaunchDaemons目錄。通過(guò)越獄后秫舌,我們可以查看/System/Library/LaunchDaemons目錄下的內(nèi)容,以下是部分服務(wù)的截圖绣檬,可以看到足陨,服務(wù)非常之多。

image

能力擴(kuò)展

搞清楚 libimobiledevice 實(shí)現(xiàn)原理后娇未,基于這個(gè)思路墨缘,我們又自行探索了其他一些服務(wù)的能力,這其中就包括 Xcode 相關(guān)的服務(wù)零抬。Xcode 為開(kāi)發(fā)者提供了專業(yè)镊讼、穩(wěn)定的工具集,而 Xcode 的工具集也是利用以上機(jī)制與 iOS 設(shè)備進(jìn)行通信平夜〉澹基于Xcode 的能力,我們實(shí)現(xiàn)了 Trace 采集忽妒、設(shè)備應(yīng)用管理等功能玩裙。

支持 Linux

工具的問(wèn)題解決了,接下來(lái)就是部署的問(wèn)題段直。我們需要面對(duì)上千臺(tái) iOS 設(shè)備接入及每天上萬(wàn)次的服務(wù)調(diào)度吃溅,且設(shè)備之間的環(huán)境需要相互隔離,互不干擾鸯檬。所以在設(shè)備及工具的部署上需要簡(jiǎn)單决侈、高效。比較好的解決方案是采用 docker 部署喧务,每臺(tái)設(shè)備及其對(duì)應(yīng)的驅(qū)動(dòng)工具都用 docker 分離開(kāi)赖歌,這樣能做到環(huán)境隔離,且部署簡(jiǎn)單蹂楣。但 Mac 對(duì) docker 的支持并不那么友好俏站,且我們的工具本身依賴 Xcode 環(huán)境。

既然 Mac 對(duì) docker 的支持不友好痊土,那我們是否能擺脫對(duì) Mac 的依賴肄扎,將設(shè)備及工具部署在 Linux 上。順著這個(gè)思路,我們開(kāi)始了對(duì)工具的第二次改造犯祠。

支持 XCTest 啟動(dòng)

工具對(duì) Mac 的依賴主要來(lái)源于 XCTest 工具的啟動(dòng)旭等,類似于 wda。我們將 XCTest 的接口封裝在了一個(gè)普通的 App 里衡载,然后在這個(gè)普通的 App 里搭建一個(gè) websocket server搔耕,這樣就可以通過(guò)網(wǎng)絡(luò)與這個(gè) App 通信,實(shí)現(xiàn) XCTest API 的調(diào)用痰娱。但經(jīng)過(guò)嘗試后弃榨,發(fā)現(xiàn)普通的 App 調(diào)用 XCTest API 并不會(huì)產(chǎn)生預(yù)期的效果。所以還需要一些特殊的操作才能使普通App具備調(diào)用 XCTest API 的能力梨睁。

我們從正常的 XCTest-Runner 入手探索其啟動(dòng)流程鲸睛。以home鍵的點(diǎn)擊方法為切入點(diǎn),通過(guò) LLDB 追蹤testmanagerd 進(jìn)程中接口的調(diào)用流程坡贺,發(fā)現(xiàn)了如下關(guān)鍵的接口:

_IDE_authorizeTestSessionWithProcessID:

分析后發(fā)現(xiàn)官辈,testmanagerd 會(huì)維護(hù)一個(gè)進(jìn)程白名單,只有將 App 的進(jìn)程 ID 加到這個(gè)白名單里遍坟,這個(gè)App 才具備調(diào)用 XCTest API 的能力拳亿。而上述注冊(cè)白名單的接口則可以通過(guò)前面提到的 lockdownd 的方式調(diào)用≡赴椋基于此肺魁,我們實(shí)現(xiàn)了擺脫對(duì) Mac 環(huán)境的依賴,在 Linux 實(shí)現(xiàn)了 docker 化部署公般。
image

四万搔、運(yùn)行效果

bdc 工具上線已有一年多。目前支撐了公司自動(dòng)化測(cè)試平臺(tái)上千臺(tái) iOS 設(shè)備每日上萬(wàn)次的設(shè)備調(diào)度及測(cè)試任務(wù)執(zhí)行官帘。自動(dòng)化測(cè)試平臺(tái)涵蓋了穩(wěn)定性瞬雹、UI、性能刽虹、單元測(cè)試等多項(xiàng)測(cè)試能力酗捌,服務(wù)公司上百個(gè)業(yè)務(wù)。

設(shè)備機(jī)架從原有的簡(jiǎn)陋設(shè)備已升級(jí)為全球機(jī)房涌哲,服務(wù)于全球業(yè)務(wù)胖缤。
image

?? 火山引擎 APMPlus 應(yīng)用性能監(jiān)控是火山引擎應(yīng)用開(kāi)發(fā)套件 MARS 下的性能監(jiān)控產(chǎn)品。我們通過(guò)先進(jìn)的數(shù)據(jù)采集與監(jiān)控技術(shù)阀圾,為企業(yè)提供全鏈路的應(yīng)用性能監(jiān)控服務(wù)哪廓,助力企業(yè)提升異常問(wèn)題排查與解決的效率。目前我們面向中小企業(yè)特別推出「APMPlus 應(yīng)用性能監(jiān)控企業(yè)助力行動(dòng)」初烘,為中小企業(yè)提供應(yīng)用性能監(jiān)控免費(fèi)資源包∥姓妫現(xiàn)在申請(qǐng)分俯,有機(jī)會(huì)獲得60天免費(fèi)性能監(jiān)控服務(wù),最高可享6000萬(wàn)條事件量哆料。

?? 點(diǎn)擊這里缸剪,立即申請(qǐng)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市东亦,隨后出現(xiàn)的幾起案子杏节,更是在濱河造成了極大的恐慌,老刑警劉巖典阵,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奋渔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡萄喳,警方通過(guò)查閱死者的電腦和手機(jī)卒稳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)他巨,“玉大人,你說(shuō)我怎么就攤上這事减江∪就唬” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵辈灼,是天一觀的道長(zhǎng)份企。 經(jīng)常有香客問(wèn)我,道長(zhǎng)巡莹,這世上最難降的妖魔是什么司志? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮降宅,結(jié)果婚禮上骂远,老公的妹妹穿的比我還像新娘。我一直安慰自己腰根,他們只是感情好激才,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著额嘿,像睡著了一般瘸恼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上册养,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天东帅,我揣著相機(jī)與錄音,去河邊找鬼球拦。 笑死靠闭,一個(gè)胖子當(dāng)著我的面吹牛帐我,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阎毅,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼焚刚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了扇调?” 一聲冷哼從身側(cè)響起矿咕,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎狼钮,沒(méi)想到半個(gè)月后碳柱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熬芜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年莲镣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涎拉。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瑞侮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鼓拧,到底是詐尸還是另有隱情半火,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布季俩,位于F島的核電站钮糖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏酌住。R本人自食惡果不足惜店归,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酪我。 院中可真熱鬧消痛,春花似錦、人聲如沸祭示。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)质涛。三九已至稠歉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汇陆,已是汗流浹背怒炸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毡代,地道東北人阅羹。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓勺疼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親捏鱼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子执庐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354