您好,登錄后才能下訂單哦!
移動APP插件化是平臺化產(chǎn)品解決系統(tǒng)限制(65535)、模塊解耦、和多團隊協(xié)作的利器。它的最大特點是模塊動態(tài)下發(fā),給產(chǎn)品帶來的收益顯而易見,但是,在百度,這套系統(tǒng)給移動端測試技術(shù)帶來了新思路
移動端線上問題定位的幾個場景:
場景一: 云端用戶反饋某功能不可用,RD猜測幾種可能觸發(fā)原因,線上收集的客戶端打點日志信息不全,無法完全確認問題。陷入死循環(huán),線上用戶持續(xù)暴露問題,線下無法穩(wěn)定復(fù)現(xiàn),不能及時定位問題。如何破?
場景二:通過客戶端預(yù)埋方式打點用戶行為,往往會出現(xiàn)打點不全的問題,而往往線上問題的定位需要這些行為日志為問題定位提供良好的復(fù)現(xiàn)步驟。 如何無需編碼,通過技術(shù)手段獲取全量用戶與客戶端交互日志?
場景三:線下很多好工具可以SDK化,給線上問題發(fā)現(xiàn)和定位帶來大量正向收益,但因為測試能力本身會影響集成app的性能,或開發(fā)團隊排期等原因,無法集成,大量線上問題無法充分暴露。如何優(yōu)美的解決這種問題?
場景四:百度的線上客戶端小流量實驗表明,線上問題實際是一種正態(tài)分布的隨機事件,TOP問題,往往只需抽樣很少量用戶即可召回,而不需要影響全量用戶
移動端線下測試的幾個場景:
場景一: 客戶端測試簡單卻又復(fù)雜,一個客戶端測試人員的簡單技能樹可能包括這些問題的分析能力: ANR、crash、卡頓、內(nèi)存泄露、內(nèi)存、CPU占用、電量分析、啟動速度分析等等一系列的技能。而往往,部分QA人員并不是全棧。并且這些工具的使用本身,就是一個工具大集合。如何讓客戶端測試人員,或非專業(yè)測試人員,無需任何背景,只需要點一點就可以具備全部客戶端問題分析能力
場景二:同剛才說的線上問題定位,線下大量的優(yōu)秀功能,并不能適用于全量用戶,因為他們本身就是傷敵八百,自傷一千的能力。如何在盡量小用戶體驗損耗的前提下,讓問題盡量的全部召回?
基于插件系統(tǒng),做一個測試插件,把我們所有覺得有用的線下測試能力打進去,同時集成業(yè)內(nèi)知名的好框架,譬如dexposed、 leakcanary等,還有一些系統(tǒng)開放了但是主版使用會影響性能的好東西traceviewer、Choreographer、ActivityLifecycleCallback等。統(tǒng)統(tǒng)打到云插件中,并通過云端已經(jīng)構(gòu)建好的動態(tài)模塊小流量系統(tǒng)下發(fā)到特定目標用戶手機中,持續(xù)暴露問題
NICE JOB!!
云插件工作原理:
云插件本身就是宿主的一個插件而已,真正能夠發(fā)揮它的測試能力的是,線下構(gòu)建的大量測試場景,以及插件本身的動態(tài)加載機制,這樣我們的測試場景就可以在線上發(fā)揮它的效力了。提到這個就不得不新鍋炒舊飯:
雙親委托機制:java的類加載機制下,子classloader可以向上查找父classloader的加載內(nèi)容,從而給云插件動態(tài)查找宿主各種類信息提供了先決條件(多進程化的插件系統(tǒng)。。請忽略我把)
dexclassloader:可以加載文件系統(tǒng)的任意JAR(包含dex文件)、zip、apk文件
patchclassloader: 只可以加載data/app/的apk文件,常用于多dex拆分項目
dexfile: 可以加載動態(tài)文件,同時提取文件內(nèi)部的類信息,這個是dexclassloader不具備的
破殼: 云插件自己的場景需要集成信息上傳類,但在編譯時,不能將對應(yīng)類編譯進插件包。這樣場景插件在被加載起來以后,就可以回調(diào)宿主的日志系統(tǒng)進行信息采集了
經(jīng)過如上,下圖中的JAR或APK中包裹的場景插件就可以被云插件動態(tài)加載進來,同時對宿主的各種類、本地空間、以及系統(tǒng)中與宿主相關(guān)的信息進行讀取、采集。至于是hook、反射、代碼注入、異常捕獲、插樁等這些只是一種手段了
注意: 下面的case,雖然說的是云插件的問題定位場景,但是不止云插件,我們后面會以SDK形式開源這部分技術(shù),所以,集成了這個SDK的app也可以這么干,但是脫離了插件系統(tǒng),本身的安全性,需要集成的開發(fā)者關(guān)注自己的安全性。 當然也可以不關(guān)注,root的手機上,你的app本身就已經(jīng)全部暴露給了***(BLESS…)
正文: 以流暢度為例,我們看如何非常快速的構(gòu)建云調(diào)試插件的case吧
流暢度:可以理解為android系統(tǒng)繪制UI的速度,理論上,人眼在1s內(nèi)接收60幀圖像才會感覺程序流暢。 android系統(tǒng)之初,流暢度一直是人們詬病的目標,直到android 4.1系統(tǒng)的時候,有了注明的project Buffer,并引入了三大元素,VSYNC(垂直同步)、Triple Buffer和Choreographer。其中Choreographer這個東西是我們今天討論的目標。它是整套機制中的協(xié)調(diào)者,并且所有l(wèi)ooper都共用一個Choreographer對象
Choreographer對外開放了一個FrameCallback的東西,在每次系統(tǒng)繪制時,都會通過這個回調(diào)doFrame函數(shù),通過這個函數(shù)可以計算出在1s內(nèi),當前頁面的繪制次數(shù)。但是問題來了:
看上圖,含義就是,此貨雖然好,但是建議是你們開發(fā)者還是不要用了。。。這如何玩,本來還想拿它上個流暢度監(jiān)控的。。此時一定會想到,我們有云調(diào)試插件。
構(gòu)建很簡單,如下,只需要把這段代碼copy到任意android工程,然后打包,注意NutXError只作為編譯依賴即可, 如果已有插件系統(tǒng), 這段代碼就可以直接被加載并運行了
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); } } }
下面這個截圖是在操作客戶端運行的時候(注意監(jiān)控case是通過云插件動態(tài)加載的喲),發(fā)現(xiàn)的一個流暢度問題。同時也可以看到,在監(jiān)控到繪制問題后,用戶停留的每個界面也被畫了出來。 然后線下就可以沿著這條trace去復(fù)現(xiàn)結(jié)果了~
是不是很酷~~~
如上,便結(jié)束了對百度在移動端測試的技術(shù)探討。然而,其實有很多沒提到,譬如現(xiàn)在已經(jīng)構(gòu)建好的自動化case有哪些、這套機制兼容性如何等,再譬如有眼尖的同學(xué)也會發(fā)現(xiàn)這套系統(tǒng)本身可能就會有兼容性問題,如何做好問題卡控,保證云調(diào)試插件(其實我們叫堅果云)有效及時回收。 其實,我們有充足的自信在線上嘗試這個東西。在廠子的線上,我們一整套動態(tài)模塊小流量系統(tǒng),云插件本身其實就被作為了一個動態(tài)模塊,當線上出現(xiàn)問題時,我們的云插件就會發(fā)揮它的價值了
本文作者:hyxbiao & tony xin
作者Email:hyxbiao@gmail.com & jiankangxin@gmail.com
有問題聯(lián)系我>>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。