一種基於動態插件系統的移動測試黑科技


背景

移動APP插件化是平臺化產品解決系統限制(65535)、模塊解耦、和多團隊協做的利器。它的最大特色是模塊動態下發,給產品帶來的收益顯而易見,可是,在百度,這套系統給移動端測試技術帶來了新思路 java

移動端線上問題定位的幾個場景android

  • 場景一: 雲端用戶反饋某功能不可用,RD猜想幾種可能觸發緣由,線上收集的客戶端打點日誌信息不全,沒法徹底確認問題。陷入死循環,線上用戶持續暴露問題,線下沒法穩定復現,不能及時定位問題。如何破? 安全

  • 場景二:經過客戶端預埋方式打點用戶行爲,每每會出現打點不全的問題,而每每線上問題的定位須要這些行爲日誌爲問題定位提供良好的復現步驟。 如何無需編碼,經過技術手段獲取全量用戶與客戶端交互日誌? app

  • 場景三:線下不少好工具能夠SDK化,給線上問題發現和定位帶來大量正向收益,但由於測試能力自己會影響集成app的性能,或開發團隊排期等緣由,沒法集成,大量線上問題沒法充分暴露。如何優美的解決這種問題? 框架

  • 場景四:百度的線上客戶端小流量實驗代表,線上問題實際是一種正態分佈的隨機事件,TOP問題,每每只需抽樣不多量用戶便可召回,而不須要影響全量用戶 ide

移動端線下測試的幾個場景函數

  • 場景一: 客戶端測試簡單卻又複雜,一個客戶端測試人員的簡單技能樹可能包括這些問題的分析能力: ANR、crash、卡頓、內存泄露、內存、CPU佔用、電量分析、啓動速度分析等等一系列的技能。而每每,部分QA人員並非全棧。而且這些工具的使用自己,就是一個工具大集合。如何讓客戶端測試人員,或非專業測試人員,無需任何背景,只須要點一點就能夠具有所有客戶端問題分析能力 工具

  • 場景二:同剛纔說的線上問題定位,線下大量的優秀功能,並不能適用於全量用戶,由於他們自己就是傷敵八百,自傷一千的能力。如何在儘可能小用戶體驗損耗的前提下,讓問題儘可能的所有召回? oop

一種移動端線上問題定位的新思路:

基於插件系統,作一個測試插件,把咱們全部以爲有用的線下測試能力打進去,同時集成業內知名的好框架,譬如dexposed、 leakcanary等,還有一些系統開放了可是主版使用會影響性能的好東西traceviewer、Choreographer、ActivityLifecycleCallback等。通通打到雲插件中,並經過雲端已經構建好的動態模塊小流量系統下發到特定目標用戶手機中,持續暴露問題 post

NICE JOB!!

雲插件工做原理: 
雲插件自己就是宿主的一個插件而已,真正可以發揮它的測試能力的是,線下構建的大量測試場景,以及插件自己的動態加載機制,這樣咱們的測試場景就能夠在線上發揮它的效力了。提到這個就不得不新鍋炒舊飯:

  • 雙親委託機制:java的類加載機制下,子classloader能夠向上查找父classloader的加載內容,從而給雲插件動態查找宿主各類類信息提供了先決條件(多進程化的插件系統。。請忽略我把)

  • dexclassloader:能夠加載文件系統的任意JAR(包含dex文件)、zip、apk文件

  • patchclassloader: 只能夠加載data/app/的apk文件,經常使用於多dex拆分項目

  • dexfile: 能夠加載動態文件,同時提取文件內部的類信息,這個是dexclassloader不具有的

  • 破殼: 雲插件本身的場景須要集成信息上傳類,但在編譯時,不能將對應類編譯進插件包。這樣場景插件在被加載起來之後,就能夠回調宿主的日誌系統進行信息採集了

通過如上,下圖中的JAR或APK中包裹的場景插件就能夠被雲插件動態加載進來,同時對宿主的各類類、本地空間、以及系統中與宿主相關的信息進行讀取、採集。至因而hook、反射、代碼注入、異常捕獲、插樁等這些只是一種手段了 

wKioL1Z6TvLDI3NXAAFEj-gGqrg942.png

實例:

注意: 下面的case,雖說的是雲插件的問題定位場景,可是不止雲插件,咱們後面會以SDK形式開源這部分技術,因此,集成了這個SDK的app也能夠這麼幹,可是脫離了插件系統,自己的安全性,須要集成的開發者關注本身的安全性。 固然也能夠不關注,root的手機上,你的app自己就已經所有暴露給了黑客(BLESS…)

正文: 以流暢度爲例,咱們看如何很是快速的構建雲調試插件的case吧

流暢度:能夠理解爲android系統繪製UI的速度,理論上,人眼在1s內接收60幀圖像纔會感受程序流暢。 android系統之初,流暢度一直是人們詬病的目標,直到android 4.1系統的時候,有了註明的project Buffer,並引入了三大元素,VSYNC(垂直同步)、Triple Buffer和Choreographer。其中Choreographer這個東西是咱們今天討論的目標。它是整套機制中的協調者,而且全部looper都共用一個Choreographer對象

Choreographer對外開放了一個FrameCallback的東西,在每次系統繪製時,都會經過這個回調doFrame函數,經過這個函數能夠計算出在1s內,當前頁面的繪製次數。可是問題來了: 
wKiom1Z6Tszym21sAAXUR_c4OgY916.png看上圖,含義就是,此貨雖然好,可是建議是大家開發者仍是不要用了。。。這如何玩,原本還想拿它上個流暢度監控的。。此時必定會想到,咱們有云調試插件。

構建很簡單,以下,只須要把這段代碼copy到任意android工程,而後打包,注意NutXError只做爲編譯依賴便可, 若是已有插件系統, 這段代碼就能夠直接被加載並運行了

public class        NutFrameMonitor extends BaseCase {    private static final String TAG = "NutFrameMonitor";    @Override    public void invoke(Context context) {        int sdkVersion = 0;        try {            sdkVersion = Build.VERSION.SDK_INT;        } catch (Exception e) {            // TODO        }        if (sdkVersion >= 16) {            try {                Choreographer.getInstance().postFrameCallback(NutFrameCallback.callback);            } catch (Exception e) {                // TODO            }        }    }    private static  class NutFrameCallback implements Choreographer.FrameCallback {        static final NutFrameCallback callback = new NutFrameCallback();        private long mLastFrameTimeNanos = 0;        private long mFrameIntervalNanos = (long)(500000000) - 1;        @Override        public void doFrame(long frameTimeNanos) {            if (mLastFrameTimeNanos != 0) {                final long jitterNanos = frameTimeNanos - mLastFrameTimeNanos;                if (jitterNanos > mFrameIntervalNanos) {                    NutXError error = new NutXError(TAG);                    error.setDetailMessage("frame Choreographer waste more than 500ms");                    error.dump();                }            }            mLastFrameTimeNanos = frameTimeNanos;            Choreographer.getInstance().postFrameCallback(NutFrameCallback.callback);        }    } } 

結果

下面這個截圖是在操做客戶端運行的時候(注意監控case是經過雲插件動態加載的喲),發現的一個流暢度問題。同時也能夠看到,在監控到繪製問題後,用戶停留的每一個界面也被畫了出來。 而後線下就能夠沿着這條trace去復現結果了~ 
是否是很酷~~~ 

wKiom1Z6TquRAH8oAAGGQFzKQBw500.png

後記

如上,便結束了對百度在移動端測試的技術探討。然而,其實有不少沒提到,譬如如今已經構建好的自動化case有哪些、這套機制兼容性如何等,再譬若有眼尖的同窗也會發現這套系統自己可能就會有兼容性問題,如何作好問題卡控,保證雲調試插件(其實咱們叫堅果雲)有效及時回收。 其實,咱們有充足的自信在線上嘗試這個東西。在廠子的線上,咱們一整套動態模塊小流量系統,雲插件自己其實就被做爲了一個動態模塊,當線上出現問題時,咱們的雲插件就會發揮它的價值了

     百度MTC是業界領先的移動應用測試服務平臺,爲廣大開發者在移動應用測試中面臨的成本、技術和效率問題提供解決方案。同時分享行業領先的百度技術,做者來自百度員工和業界領袖等。
本文做者:hyxbiao && tony xin

     更多幹貨分享請關注「百度MTC學院」http://mtc.baidu.com/academy/article

相關文章
相關標籤/搜索