解放程序猿(媛)的雙手—iOS UI自動化測試

轉載地址:http://tmq.qq.com/2016/06/uitestingiosautomation/?utm_source=tuicool&utm_medium=referral


前言

隨着移動互聯網時代的蓬勃發展,移動終端的自動化測試也在業界日益活躍,總體來看在Android平臺上的自動化工具和實踐比較多,但是說到iOS平臺無論從自動化工具的數量還是質量上就陡降了。究其原因,無外乎是iOS系統的封閉性,加上相對Android用戶的數量少,導致對這個平臺系統的自動化進展緩慢,據筆者瞭解到的情況,很多iOS平臺的測試人員還處於純手工測試模式,自動化程度和Android平臺無法相論,更別提和PC端相比了。

然而越是困難的事,越是研究的少,就越發有挑戰性。有挑戰性的事大多又會帶來不菲的收益,如果能在iOS上做出大規模可持續運行的自動化測試,那麼對iOS的測試演進無疑是一次大的推動。

手機QQ瀏覽器(iPhone)測試小組的同學在比對和實踐了業界已有的iOS自動化工具,總結提煉了對比,如下表所示。

QQ截圖20160624145248
 
表中沒有列的內容是穩定性,實踐中看來上述除UITesting之外的工具穩定性都相對一般,會出現自身框架導致的各種閃退,以及性能越來越差的問題。

因此iOS平臺上除了Monkey測試採用了自動化方式,以及部分性能測試輕度使用了一些自動化工具,大部分功能測試還是依賴於人的操作。移動APP更多的場景是面向用戶,面向界面操作,UI測試就非常直觀和重要,因此我們致力於尋找一種穩定性高,且易於掌握的自動化測試工具。

 

久旱逢甘霖

蘋果公司在2015年推出的Xcode7中引入了UI Testing工具,該工具配置相對簡單,還支持錄製回放功能,運行速度很快,測試代碼也可以調試,使用OC作爲腳本測試語言兼容性較好,支持UIWebView,支持截圖功能,最重要的是穩定性高。

1

其實選用一個工具,最看重的就是穩定性和可調試。可調試性不必多說,就是剛需。而很多工具沒有被很好的應用就是因爲穩定性較差,UI Testing是蘋果開發的,和被測程序的兼容性好,實踐證明,確實能夠徹夜穩定運行腳本,未見因工具自身原因導致的閃退。性能方面也影響較小,後期發現一些截圖操作會有一點點影響速度,但是整體運行還算良好,沒有明顯變差。

在大量工具都無法在iOS上施展拳腳時,UI testing姍姍而來,帶給我們驚喜和希望。

 

必經之路

工具是好工具,但是如果想在項目中實際應用起來,還是會遇到許多問題和困難,這裏給大家分享下我們的磨合期。

第一個挑戰:門檻要低

要使用這個工具,撲面而來的問題就是怎樣快速上手,也即學習成本和投入產出比的問題。地球人都知道OC語言並不是一種容易快速上手學習的語言,加上底層是XCTest接口,錄製後能看到的實現就是下圖這樣的,看着很凌亂有沒有?

2

因此我們需要做的就是進行封裝。封裝包含接口封裝和特殊控件的封裝兩部分。

接口封裝有兩層,一層主要處理彈窗,異常,超時等待,手勢處理等操作,二層是把控件類型和手勢合二爲一,提供腳本使用。實際腳本編寫者就可以直接調用,命名和使用方式都具備高可讀性和可用性,另一方面底層的接口修改,不會影響到上層的函數表現形式,這對自動化用例編者來說也降低了門檻,不必關注底層接口的細節變動。

3

例如上圖所示,瀏覽器多窗口界面向左滑動就可以刪除頁面,可以選擇刪除第一個頁面。將這個操作封裝起來如下圖所示,後續使用即可直接調用該函數,只需傳入對應參數即可。

4

 

特殊控件的封裝。一般應用於控件無法尋找到對應的唯一標識,或者層級比較多的情況下,通過錄制的方式,讀取控件屬性,將其打包成一個整體,再後續使用時可以直接調用。

5

例如上圖所示是瀏覽器多窗口的管理界面,右下角有個返回按鈕,通過查看xml結構無法獲知唯一標識,通過錄制的方式確定控件結構。對錄製的內容進行加工處理後,封裝爲特殊控件,如下圖所示,存放於指定文件內,方便後續使用。

6

使用中,可以直接調用已經封裝好的接口,每個接口都包含一個或者多個固定參數,和一個可變參數。固定參數按照所給出的類型傳值就可以了,而可變參數,需要我們按照一定的格式進行參數傳遞。舉例可變參數格式:VariableParameter:@” StepName=切換小說書架爲宮格模式&LogLevel=WARN”,其中多個參數使用&符號連接,每一個單獨的參數使用KEY=VALUE的形式。

第二個挑戰:靈活編譯

在自動化測試中經常遇到的問題是配置環境和單例運行的問題。

首先環境配置會不會很複雜,很大程度上制約着使用者的使用頻率。相比較APPium的複雜設置,UI testing的配置就簡單明瞭多了。

  1. 添加服務端配置。需要將UITestServer.xcodeproj添加到目標工程的thridparty文件夾下面。UITestServer.xcodeproj是自研服務器,主要功能是:嵌入被測試APP中,實現端口監聽,服務開啓,消息獲取,消息處理,各種事件功能(截屏,獲取被測試APP日誌信息,獲取內存,cpu,網速,流量等功能),還可以擴展。
  2. 配置被測APP。需要在被測APP的主加載函數中加入監聽服務端口。爲了不影響發佈版本的使用,我們採用DEBUG模式。
  3. 配置QBUITests(名字自定義)組件部分,該部分主要是我們的自動化測試框架部分,包括各種自動化組件,自動化腳本,配置信息等。需要將自研文件夾UITestUtils,SystemResources,SpecialElement,ScreenShot,Log,ScriptInterface全部拖動到QBUITests Target下面。

經過上面的配置,框架配置基本完成。

接下來看單例運行問題,如下圖所示是小說模塊的自動化腳本頭部,包含開頭的初始化操作,直接可以運行單例“test311001”,也可以進行正常的調試,也可以指定運行全部用例或者部分腳本。

7

第三個挑戰結果可查

做UI自動化也好,做監控或者准入測試也罷,最終都要有個輸出結果。一般來說對於自動化測試的結果要具備兩點:截圖和日誌。截圖可以時時截圖,也即可以讓自動化設計者或者測試人員隨時獲取想要的結果圖片,也可以設置發生錯誤時自動截圖。日誌系統就要詳細記錄操作過程,在確認問題是可以一步步通過日誌追溯。

UI Testing除了控件識別和簡單操作外,並沒有提供屏幕截圖功能,我們需要自己完成屏幕截圖功能,而且還要能夠在各種封裝好的函數中靈活使用截圖功能。如下圖所示,在自動化用例腳本中使用函數時,可以隨時在可變參數裏設置LogLevel=WARN,即可在操作執行過程中進行截圖。

8

當然在程序運行異常或者元素找不到的時候也會自動截圖。這些截圖的操作都默認放在封裝函數裏了,使用者不必單獨設置。

系統日誌的獲取分爲兩種,一種是過程中的操作記錄,一種是內存之類的性能日誌。日誌的獲取需要用到跨進程通信,前者主要是記錄自動化用例執行過程中的操作步驟和截圖信息,後者主要是獲取設備的系統性能數據,例如內存、CPU、網絡等。生成的本地log如下圖示。

9

 

最終整合到日誌系統(後文講解)下圖。

10

 

發展壯大

在初次磨合後,基本上有了本地單機運行自動化的能力,但是要真正對項目有所幫助,就必須有比較好的運行方式和結果展示,因此對這個自動化的研究還需要進一步發展。

1)整體架構

首先要對基於UI Testing的自動化整體架構有個瞭解。如下圖所示,使用系統提供的XCTest接口、消息處理、驅動模塊、系統資源獲取,在中間層進行封裝,包括控件調用封裝,特殊控件封裝,截圖模塊,日誌處理模塊。這些內容在上文都有講述。

11

關於整體架構的內容在圖中的最上層。一個是集成在XCODE裏邊的自動化運行框架和腳本,另一個是分析log日誌的自動化log日誌分析系統。如上圖所示是在基於控件調用驅動的基礎上,使用自動化腳本和配置文件完成自動化測試的工作。然後使用日誌分析系統,包含日誌分析、展示、郵件等,給到項目團隊以完整的可視化報告。

 

2)日誌系統

日誌分析系統是使用Python開發的系統,所以其是獨立於XCODE框架的,當自動化腳本執行完成後,需要把log日誌傳到分析系統下,然後使用該系統分析出日誌,方便用戶查看腳本錯誤信息,分析定位問題。

自研的日誌分析系統可以將每次運行的日誌升成html格式,如下圖所示。

12

詳細腳本日誌介紹,如下圖所示。

13

步驟詳細信息,如下圖所示,一般只需關注紅色錯誤信息。

14

通過該日誌系統就可以獲得良好的可視效果,方便問題追蹤和回溯。

 

3)持續集成

功能的自動化測試,最終的期望還是能夠隨着版本進行持續測試。有些比較好的應用場景:准入測試、開發自測、迴歸測試。不管是哪種應用場景,最佳方式都是將自動化框架合入主線,方便項目組的不同成員隨時在任何開發機上運行。

但是!這裏是iOS平臺,有一種憂傷叫做蘋果審覈不通過,有一種致命拒絕叫做查出私有API。雖然配置簡單,合入主線跟隨代碼構建看起來不是個難事,但是難就難在需要打包升成版本的時候不能將自研部分的服務器代碼編譯進去,這部分會經常含有私有API(一些功能的實現必須要用到私有API)。因此我們採用了動態關聯的方式,在主函數所在的文件中加入下圖所示內容。既能順利將框架合入開發主線,又可以在編包發佈時不編譯這部分代碼。

 

實踐效果

凡事都講究個投入產出比,前期做了大量的預研和實踐工作,那究竟在項目實踐中能發揮怎樣的效果呢?接下來爲大家展示一下。

1)部署情況

目前手機QQ瀏覽器(iPhone)項目上,已經採用這種基於UI Testing的自動化測試方法進行BVT建設,每天晚上測試白天提交到主線的最新代碼,保障主線質量穩定,併爲第二天早上的提測包做一個准入測試。

在部署時考慮到版本迭代以及UI變更大的問題,主要是在瀏覽器基礎FT上進行了大量自動化測試部署,還對用戶訪問的TOP頁面進行檢測,如下圖所示。確保合入主線的代碼不會影響到瀏覽器基礎功能,及時發現問題,避免提測後再暴露問題,造成時間和資源的浪費。

15

發現有問題的地方還可以進入詳情查看,如下圖所示點擊測試LOG鏈接。

16

 

另外對一些瀏覽服務SDK也進行了自動化測試監控,如下圖所示。

17

 

2)投入產出比

投入產出比的問題,要看兩個方面,好比天平的兩端,一端是投入,一段是產出。得產出重過投入纔是一個好項目,值得長期運營。

18-1

如上圖所示,我們的投入成本可以分成兩塊,分別是一次性成本和線性成本。

一次性成本:框架研發(1個人2個月)+配置和部署(4人0.5天)+學習成本(3人1天)。這個一次性成本主要消耗在框架的研發上,以及測試人員的初始培訓上,後續只有新加入測試人員纔會增加這個成本。事實證明在一次性成本上的投入非常值當,好的框架可以保證提高後期運維階段的穩定性和使用的簡易性。

線性成本:自動化用例編寫(平均14分鐘/條),每日需要維護的成本(8分鐘左右)。線性成本隨着時間的推移可能會產生變化,例如自動化用例隨着測試人員的熟練程度單條用例的編寫時間會減少,每日需要維護的成本隨着用例數的增多和需求變動增多會增高,這些都在預期範圍內。

產出方面,我們的評估分爲客觀和主觀兩方面。

客觀:

  1. 前置bug暴露時間。BVT每日運行,因此總會提前於正式提測前暴露問題。目前是部署在主線上,主線的提測頻率大約40天能提測10次左右,也即平均下來差不多4天才能提測一次,一旦BVT發現問題,平均能前置三天發現。由於數量都是平均來算,因此只能大約估值,例如發現了29次問題,前置時間就是29*3天=87天。
  2. 減少提測拒絕次數,節省人力時間成本。由於BVT裏的自動化用例全部是基礎核心用例,一旦出現運行問題,就是不符合准入測試標準的。在沒有BVT的時代,提測前都是開發手工自測和測試手工驗證的方式進行,一旦發現不符合測試條件的bug,就會打回,這種情況下就會消耗不少的人力和時間。有了BVT後,這種情況大大減輕,開發可以自己運行自動化腳本做基礎功能自測,測試每日監控也在運行檢測。 目前手工運行一遍自動化的用例大約需要200分鐘,機器在夜晚用60分鐘就搞定,每個版本的拒測次數大約是2次左右。如果用狂野的算法應該是節約了200*2=400分鐘,低調點的算法,應該是“從開始測試到發現導致拒測的bug所用的時間”*拒測次數,但是這個數據暫時來說不可考。

 

主觀:

爲什麼要放上主觀收益呢,因爲客觀上節省的時間,在主觀上還要有個內心“更淡定”了的感受。總體來說BVT的部署,大大提高了測試在項目組的影響力,從此iOS上的測試從純手工邁入了新時代,每日版本質量也有了持續穩定的檢驗,全項目組的內心也更加淡定了。

 

3)運營數據

如下圖所示是每日發現問題的統計,金色的線是確認是bug的數量,藍色的是BVT每日報出來的問題,可以看出兩線基本重合的點比較多,這反映了誤報率相對維持在一個比較低的水平。

20-2

發現的問題中主要分爲三類,如下圖所示,分別是純誤報(因爲腳本的穩定性導致的)、UI變動(包含被測元素變動、需求變更)和真實bug。如下圖所示是統計的兩個月的數據,可以發現UI變動導致的問題佔總發現問題的比例相對較低。這些數據是在沒有與開發約定代碼規範的時候,隨着後期的合作,這部分UI變動導致的問題中的元素屬性變動問題將會降低,但是純需求變動的問題還是保持一定的比例。

24-3

 

寫在最後

最後,還是需要和讀者交流下這個自動化方案的問題和未來。

目前已知的問題是基於UI Testing的自動化測試方案需要的硬件要求。聯機操作或者模擬器,得有iMac,操作系統得是OS10.10.5及以上版本,Xcode版本得是7.1及以上,Python版本2.7及以上,內存2G及以上爲佳。沒有這個配置,恐怕無法良好的運行自動化測試。

還有一個性能問題,已經封裝好的工具腳本總數理論上控制在1000個以內,可穩定運行10小時以上。在這穩定運行的10小時內,可以滿足我們的自動化需求,但是時間超過幾個小時後,還是會有些許減速,可以通過修改底層消息傳遞機制,提升傳遞效率,減少截圖運行時間,也是今後自動化測試繼續優化的方向。

未來呢,繼續擴大腳本覆蓋範圍,對特殊控件做封裝,對函數的靈活性做優化,降低自動化測試的准入門檻,提升自動化測試的效率,期待更多同行業的牛人一起探討!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章