唐文博,熊彩鈴,王慧亞
(四川大學計算機學院,成都610065)
在過去的幾年中,我們目睹了移動應用程序業務的驚人增長。根據最近的報道,目前最流行的Android 平臺應用市場Google Play 提供了超過一百萬個應用[1]。和傳統的軟件一樣,在應用程序發布之前需要對其進行充分測試,以確保其行為正確。隨著智能手機的快速發展以及日益激烈的市場競爭,廠商需要頻繁地更新應用程序以吸引用戶,因而快速迭代周期導致測試所需的資源如時間、人力等受到很大的限制,使得傳統的手工測試方法難以實現有效的測試,因此自動化測試的重要性越來越高。
GUI 具有良好的交互性,相對于傳統的DOS 界面,GUI 更加友好和直觀,用戶能夠更加輕松地使用Android 程序。目前幾乎所有的Android 應用程序都有GUI,GUI 在整個應用程序中的代碼量占比也達到了60%[2]。GUI 在應用程序中占有非常重要的地位,因此目前GUI 測試已經成為了Android 自動化測試中最常用的方法[3]。
在GUI 自動化測試過程中,測試輸入自動生成是資源消耗最大,也是最關鍵的步驟。測試輸入的質量與測試覆蓋率有直接關系,也能夠極大地影響自動化測試的有效性。因此大量學者針對測試輸入自動生成進行了研究。本文對當前Android 測試輸入自動生成相關研究進行綜述,分析了相關研究的優缺點并指出了當前研究面臨的挑戰。
Android 應用測試輸入可分為事件輸入(將用戶的手勢動作發送到GUI 上以觸發事件)與數據輸入(應用數據輸入與環境輸入)[4],由于本文主要討論Android 平臺上的GUI 測試輸入,因此我們這里只考慮事件輸入,我們將測試輸入的生成過程定義如下:
(1)初始化一個運行環境e,將被測應用P 在其上運行以到達一個初始狀態s0∈S0。
(2)循環地觀測應用系統的狀態直到滿足某個終止條件,并利用觀測到的狀態構建GUI 模型,GUI 模型能夠反映應用程序上事件的轉換過程。
(3)根據GUI 模型,采取一定的策略生成測試輸入,將其發送到應用系統上以探索應用系統的狀態空間S。
為了保證測試質量,應用系統的狀態空間S 必須被有效地探索,也就是我們構建的GUI 模型需要盡量完整。同時為了減少測試過程中時間的開銷,需要保證生成的測試輸入盡量不包含冗余路徑。大量的學者針對上述問題進行了研究。
當前針對GUI 測試輸入生成的研究,主要可以分為三種,分別是隨機策略、基于模型的策略以及基于目標的策略,由于基于模型的策略能夠有效地避免生成冗余測試,同時幫助開發者快速定位出故障的地點,因此基于模型的策略成為了當前GUI 測試的常用方法,本節將著重介紹基于模型的策略。
隨機策略指隨機生成測試輸入并輸入到GUI 上,最典型的工具便是Google 官方提出的Monkey[5]工具,該工具能夠隨機生成類似用戶的測試輸入并輸入到手機界面上,然后模擬用戶的點擊等手勢,以及一些系統級的事件。MonkeyRunner 同樣是Android SDK 自帶的測試工具,它可以用于做功能測試,回歸測試并且可以自己定義測試擴展,靈活性較大。Dynodroid[6]對Monkey 進行了改進,它能夠從隨機生成的測試輸入中刪除掉冗余測試,從而提高了測試效率。
基于模型的策略指通過構建GUI 模型生成測試輸入。Choi.w[7]等人提出了SwiftHand 算法,該算法能夠自動生成GUI 的測試輸入序列。該算法使用機器學習來在測試期間學習應用程序的模型,使用學習后的模型來生成訪問應用程序未探索狀態的用戶輸入,并在生成的輸入上使用應用程序的執行來完善模型。該算法的一個關鍵特征是它避免了重新啟動應用程序,因而提高了效率。此外,Choi.w 通過使用一種名為DetReduce 的啟發式技術,在給定通過運行自動GUI測試工具生成的大型測試輸入的情況下,為GUI 應用程序創建小型回歸測試輸入。DetReduce 通過識別和消除現有的自動GUI 測試工具引入的某些常見形式的冗余,極大地減少了最小化GUI 測試輸入所需的時間。
D.Amalfitano[8]開發了一款名為AndroidRipper 測試工具,該工具將基于模型的技術用于Android 應用程序并執行自動化測試,該研究成為了之后大量研究的基礎。R.Mahmood[9]等人開發了一個測試框架,通過構建GUI 模型生成有效的測試輸入。Cao Y 等人[10]提出了一種針對Android 應用的基于模型的GUI 測試技術。該方法將等效小部件分組到一種狀態中,并設計了一種新的基于反饋的探索策略,該策略根據已觸發的搜索項的執行結果動態調整操作的優先級,并傾向于選擇可以到達應用的新狀態的操作,避免了局部和重復的探索。為了捕獲應用程序運行過程中的信息以構建GUI 模型,Jamrozik K 等人[11]開發了Droidmate,Droidmate 能夠探索應用程序,在運行時反復讀取設備GUI并監視對Android API 方法的調用,并且根據該數據決定要執行的下一個GUI 操作(單擊、長按、文本輸入等),并提供了探索策略。該過程一直持續到滿足某些終止標準為止。
W.Yang 等人[12]通過混合分析的方法提高了GUI模型生成的準確性,混合分析指將動態分析和靜態分析結合起來對應用程序進行探索,混合分析既能夠解決靜態分析方法無法獲取應用程序動態運行時的狀態信息的問題,又能彌補動態分析過程中遇到的路徑不可達的問題[13]。該研究通過對源代碼執行靜態分析,并將得到的信息用于支持應用程序的動態探索和GUI 模型生成過程,提高了GUI 模型準確性。
盡管混合方法能夠提高模型的準確性,但由于大多數現有的方法都是通過逆向工程創建應用程序的模型。而由于逆向工程方法的不完備性,應用模型不能廣泛地捕捉應用的動態行為,因此混合分析方法往往缺乏全面性。為了解決這個問題,D.Amalfitano 等人[14]開發了Mobile GUITAR 工具,該工具提出了一個高效的應用程序控件探索算法,在避免了靜態分析帶來的復雜性的同時,提高了遍歷的效率,保證了生成的GUI模型的完整性,為高效的基于模型的Android GUI 測試鋪平了道路。
由于某些應用程序行為只能在提供特定輸入后才能顯示。因此測試工具需要使用更復雜的技術(例如符號執行和進化算法)來指導探索以前未發現的代碼[15],這就是基于目標的方法,該方法往往是針對某個特定行為進行檢測,典型的應用場景是對應用程序進行惡意檢測[16],例如N.Mirzaei 等人使用符號執行方法[17]進行測試,試圖檢測出更深層次的故障。
盡管基于目標的策略提高了故障/錯誤檢測能力并揭示了其他工具無法發現的錯誤,但是這些方法需要相對復雜的數據或分析技術,例如使用完整源代碼的靜態分析,因此需要消耗大量的資源[18],同時該方法的拓展性較差,難以應對頻繁的需求變更。
通過對當前GUI 測試輸入自動生成的相關研究,我們可以發現仍然存在以下幾點問題值得深入研究和改進:
(1)由于應用程序的GUI 存在大量的UI 元素,而不同的UI 元素與用戶的交互方式不一定相同,UI 元素與其可能支持的交互行為的排列組合數目是非常巨大的,因此我們可以認為GUI 狀態空間S 是無窮的。因此在構建GUI 模型的過程中會不可避免的遇到了軟件界通用技術瓶頸——狀態爆炸問題,這使得測試輸入生成技術無法在有限的測試資源下遍歷整個狀態空間,只能探索一部分狀態。由于不同的測試過程目的不同,其對于不同的狀態有著不同的重要性評估。如何生成測試輸入以優先探索到所服務的測試過程認為更重要的狀態,以更好地服務測試過程,是測試輸入生成技術的一大挑戰。
(2)由于狀態空間以及狀態轉移方式的未知性以及狀態空間的無窮性,很難在有限的測試資源內精準地構建GUI 模型。測試輸入生成技術無法準確地獲知生成什么測試輸入可以進一步探索狀態空間未被探索的部分。有一些測試輸入不會導致應用系統狀態的轉移,如應用當前不可處理的輸入。而有一些測試輸入只會探索已經探索到的狀態。由于無法準確識別這些輸入,狀態空間探索容易困于局部,影響生成的測試輸入的有效性。同時,狀態空間中存在一些深層狀態,需要特定的測試輸入序列才能夠探索到。一些狀態需要特定的數據輸入(如登錄賬號密碼等)才能夠探索到,而另一些狀態需要一個特定的長測試輸入序列(如多次交替發送兩個點擊輸入)才能夠探索到。由于狀態空間的未知性,測試輸入生成技術無法準確得知所需的測試輸入,從而很難探索到這些狀態。因此如何構建完成的GUI 模型,是測試輸入生成技術的另一大挑戰。