android framework層測(cè)試微指南

framework測(cè)試

framework層測(cè)試簡(jiǎn)介

framework層測(cè)試也是android 移動(dòng)端測(cè)試的領(lǐng)域搂蜓,但是和更上層的應(yīng)用測(cè)試不同访得,應(yīng)用測(cè)試更偏重于應(yīng)用是否正確實(shí)現(xiàn)了業(yè)務(wù)邏輯;而framework層測(cè)試更偏重于能否正確向上層輸出能力缚甩。

android framework介紹

做移動(dòng)測(cè)試的,android整體框架圖肯定是了然于心的丽惶,從底層往上的順序甲捏,Android系統(tǒng)架構(gòu)由5部分組成含蓉,分別是:Linux Kernel、Android Runtime帮哈、Libraries膛檀、Application Framework、Applications;Framework層正處于應(yīng)用層之下咖刃,這也可以看出它的作用:為應(yīng)用層輸出能力泳炉。

輸出的能力包括但不限于:為上層應(yīng)用提供各種api、提供各種組件和服務(wù)嚎杨、管理應(yīng)用的活動(dòng)生命周期等等胡桃。

framework層測(cè)試內(nèi)容

既然framework是為上層提供能力的,作為我們的測(cè)試對(duì)象磕潮,我們的測(cè)試內(nèi)容自然也和這些息息相關(guān)翠胰,包括但不限于:framework層接口的測(cè)試(功能、穩(wěn)定性自脯、安全性等等)之景、底層能力測(cè)試(比如私有的按鍵功能、自定義的輸出日志等等)膏潮、系統(tǒng)修改測(cè)試(比如裁剪系統(tǒng))等等锻狗。

framework層測(cè)試方法

實(shí)際上,盡管framework層的需求種類繁多焕参,但是在測(cè)試方法上轻纪,無非也就是兩個(gè)維度來處理:自上而下的測(cè)試,或者是自下而上的測(cè)試叠纷。

自上而下的測(cè)試

自上而下的測(cè)試方法刻帚,其實(shí)也就是站在頂層的視角看需求;無論framework新增或者修改了什么涩嚣,總歸是要給上層輸出能力的崇众,或者是在上層有自己的表現(xiàn)方式。要么是上層可以使用到提供的能力航厚,要么是你的修改在上層有直接或者間接體現(xiàn)顷歌,那么我們就直接對(duì)其“表象”進(jìn)行驗(yàn)證,間接測(cè)試framework層的能力幔睬。

如果是對(duì)系統(tǒng)底層能力或者對(duì)系統(tǒng)修改的驗(yàn)證的話眯漩,其實(shí)和傳統(tǒng)的app測(cè)試差不多,因?yàn)樗麄兌加斜憩F(xiàn)的實(shí)體麻顶;app的測(cè)試可以直接從ui層看到結(jié)果赦抖,而對(duì)系統(tǒng)能力或者系統(tǒng)修改的測(cè)試,一般也可以在系統(tǒng)的ui上看到結(jié)果澈蚌,或者一些是隱形的修改摹芙,也可以通過adb命令直接看到結(jié)果灼狰。

而在framework為上層提供的能力上宛瞄,往往并沒有實(shí)體ui可以看到表現(xiàn),直接使用業(yè)務(wù)的應(yīng)用作為載體的話,其復(fù)雜度太高份汗,也不符合分層測(cè)試的理念盈电,出現(xiàn)問題難以判斷是業(yè)務(wù)應(yīng)用的問題還是framework層的問題;因此杯活,我們采用“自造”載體的形式匆帚,即自己開發(fā)一個(gè)app作為載體,和業(yè)務(wù)app不同的是旁钧,自造的app保持最小功能吸重,僅通過ui或者廣播等形式,將待測(cè)framework層的能力暴露出去歪今,通過在ui上直接操控framework層的接口嚎幸,然后觀察其結(jié)果,間接測(cè)試到framework層的能力寄猩。

自下而上的測(cè)試

自下而上的測(cè)試方法嫉晶,就比較直接了當(dāng)了,就是直接針對(duì)提供的底層能力測(cè)試田篇,例如對(duì)framework層的接口測(cè)試替废,通過單元測(cè)試的方式,對(duì)接口進(jìn)行各方面的測(cè)試泊柬,從而在底層保障framework層的能力椎镣。

這種方式可能傳統(tǒng)的功能測(cè)試同學(xué)不太熟悉,因此下面著重的介紹一下framework層接口測(cè)試的流程和方法兽赁。

framework層接口測(cè)試

在framework測(cè)試中衣陶,最為原始的測(cè)試需求應(yīng)該就是對(duì)新增或者修改framework層接口的測(cè)試,本質(zhì)上闸氮,對(duì)framework接口的測(cè)試也是接口測(cè)試的一種剪况,他可以類比于web的接口測(cè)試,更容易讓人理解蒲跨;但和單元測(cè)試更為接近译断。

framework接口測(cè)試和web接口測(cè)試異同

和web接口測(cè)試的相同點(diǎn)在于,二者都是對(duì)輸入輸出的校驗(yàn)或悲,web接口是在網(wǎng)絡(luò)協(xié)議的基礎(chǔ)上孙咪,對(duì)服務(wù)器進(jìn)行請(qǐng)求,可以想象成網(wǎng)絡(luò)協(xié)議是高速公路巡语,請(qǐng)求則是奔馳的汽車翎蹈,對(duì)汽車來說,高速公路是公共建設(shè)男公,很多協(xié)議如https荤堪、dubbo等都是公共基礎(chǔ),不需要自己再去施工的;而對(duì)于framework接口來說澄阳,這條路就未必是統(tǒng)一的拥知,因?yàn)閷?duì)于rom級(jí)的產(chǎn)品來說,會(huì)涉及到很多在framework層新增或者修改的東西碎赢,這部分不在android的官方sdk里低剔,因此,需要一些手段自己構(gòu)造測(cè)試條件肮塞,也就是自己去把路修好襟齿。

framework接口調(diào)用方式

如何去修路?首先我們需要地基枕赵,也就是請(qǐng)求的環(huán)境基礎(chǔ)蕊唐,web接口可以直接借由網(wǎng)絡(luò)通道去請(qǐng)求到服務(wù)器,而framework接口的請(qǐng)求烁设,需要請(qǐng)求端本身在含有修改后的framework層的android環(huán)境里替梨。

我們采用的方式,是自己開發(fā)一個(gè)app装黑,安裝于待測(cè)的android環(huán)境里副瀑,通過android junit 或者實(shí)現(xiàn)按鈕去請(qǐng)求(調(diào)用)接口。

這里有個(gè)問題恋谭,就是我們?cè)诒镜鼐幾g環(huán)境下糠睡,直接調(diào)用新增或者修改的framework層接口的話,是沒法調(diào)用的疚颊,因?yàn)楸镜豷dk是android官方sdk狈孔,是不含我們私有內(nèi)容的,因此材义,我們首先解決本地的編譯問題均抽。

一般來說,有兩種方法:

  1. 由開發(fā)直接提供給你接口方法所在的jar包其掂,你在需要調(diào)用的地方引用該jar包油挥,直接調(diào)用jar包內(nèi)開發(fā)好的接口;
  1. 開發(fā)如果沒有給jar包的話款熬,可以我們自己按照接口的設(shè)計(jì)說明文檔深寥,實(shí)現(xiàn)一個(gè)同名的接口類/方法,這樣編譯可以通過贤牛,而在實(shí)際環(huán)境執(zhí)行的時(shí)候惋鹅,是會(huì)優(yōu)先找系統(tǒng)內(nèi)實(shí)際的方法的。

framework接口驗(yàn)證途徑

我們預(yù)備了幾個(gè)途徑驗(yàn)證接口:

  1. 在開發(fā)的app內(nèi)殉簸,采用界面ui形式闰集,例如提供表單和按鈕沽讹,來進(jìn)行接口參數(shù)的輸入和驗(yàn)證,這個(gè)途徑一般用于給功能測(cè)試人員返十,進(jìn)行快速簡(jiǎn)單的驗(yàn)證妥泉,或者充當(dāng)工具的角色椭微,通過調(diào)用接口快速開啟系統(tǒng)提供的某種功能洞坑;
  1. 在開發(fā)的app內(nèi),預(yù)留廣播蝇率,這樣可以通過外部shell發(fā)送廣播來調(diào)起相關(guān)的接口迟杂,而無需在界面打開;這個(gè)途徑一般用于給其他類型的自動(dòng)化測(cè)試提供接口的使用途徑本慕;
  1. 是借用android的單元測(cè)試框架排拷,android junit,直接在代碼層進(jìn)行接口測(cè)試锅尘。

使用junit進(jìn)行framework層接口測(cè)試

下面主要說一下如何用junit進(jìn)行framework層的接口測(cè)試监氢。

測(cè)試工程搭建

  1. 新建Android工程
    和web接口測(cè)試不同,framework層的接口測(cè)試首先需要一個(gè)測(cè)試環(huán)境藤违,這個(gè)環(huán)境一般使用是新建一個(gè)Android工程浪腐,也就是創(chuàng)建一個(gè)app;這個(gè)app將成為測(cè)試工程和framework層接口溝通的橋梁顿乒,因?yàn)閍ndroid junit測(cè)試工程就是在應(yīng)用的子線程下執(zhí)行的(@UiThreadTest 時(shí)议街,測(cè)試case將在ui線程中執(zhí)行)。
  1. 集成待測(cè)接口
    新建完Android應(yīng)用工程后璧榄,我們需要把我們自己開發(fā)或者修改的framework接口集成在工程內(nèi)方便測(cè)試時(shí)調(diào)用特漩;這里就使用上面介紹的兩種方法,即新建待測(cè)試接口同名的類/方法骨杂,或者直接引用sdk(jar)包調(diào)用涂身。
  1. 新建junit測(cè)試工程
    android工程新建完成并集成了待測(cè)接口后,接下來直接新建junit測(cè)試工程即可搓蚪。

junit基礎(chǔ)語法

首先是基礎(chǔ)語法访得,junit和其他的測(cè)試框架基本規(guī)則都很相似,下面說一下大體的操作陕凹。

  • 新建測(cè)試類
    測(cè)試類由注解提供專門的運(yùn)行方式悍抑,加了指定的注解的類即可成為測(cè)試類,基本的測(cè)試類類似如下形式:
    @RunWith(AndroidJUnit4.class)
    public class TestClass001  {
      ...
    }
  • 新建測(cè)試方法
    測(cè)試方法也有指定的注解杜耙,只有加了該注解的方法才會(huì)被判定為測(cè)試類搜骡,并用junit框架的規(guī)則執(zhí)行,簡(jiǎn)單來說就是如果你執(zhí)行測(cè)試類佑女,那么其實(shí)他會(huì)找到所有加了注解的測(cè)試方法并執(zhí)行记靡,典型的測(cè)試方法類似如下形式:
    @Test
    public void testSomething() {
        ...
    }
  • befor和after
    注解@Before和@After用于測(cè)試前準(zhǔn)備和測(cè)試后清理谈竿,他們會(huì)在測(cè)試方法執(zhí)行前和執(zhí)行后運(yùn)行,或者換個(gè)名詞可能更熟悉些摸吠,就是一些常用測(cè)試框架內(nèi)的setup()和teardown()空凸,一般類似如下形式:
    @Before
    public void setUp() throws Exception {
        ...
    }

    @After
    public void tearDown() throws Exception {
        ...
    }
  • 運(yùn)行測(cè)試
    測(cè)試類和其中的測(cè)試方法寫完之后,就可以運(yùn)行測(cè)試了寸痢,如果是as編寫的話呀洲,可以直接點(diǎn)擊測(cè)試類旁的運(yùn)行按鈕運(yùn)行測(cè)試類,或者點(diǎn)擊測(cè)試方法旁邊的運(yùn)行按鈕運(yùn)行單個(gè)測(cè)試方法啼止;如果需要測(cè)試多個(gè)或者指定的幾個(gè)測(cè)試類道逗,可以借由junit自帶的suite管理,新建一個(gè)suite類献烦,類似如下形式:
    @RunWith(Suite.class)
    @Suite.SuiteClasses({
        TestClass001.class,
        TestClass002.class,
        ...
        })
    public class ExampleInstrumentedTest {
        ...
    }

在注解里添加你需要運(yùn)行的測(cè)試類滓窍,然后直接運(yùn)行該suite類即可。

設(shè)計(jì)接口測(cè)試用例

用例設(shè)計(jì)思路

framework接口測(cè)試用例的設(shè)計(jì)和web接口測(cè)試用例基本思路都是一致的巩那,大約從以下幾個(gè)方向考慮:

  1. 單接口的各種正反向接口參數(shù)輸入吏夯,對(duì)比接口設(shè)計(jì)文檔檢驗(yàn)輸出;
  2. 接口之間組合成業(yè)務(wù)流即横,形成各種正反向業(yè)務(wù)場(chǎng)景噪生,對(duì)比需求文檔檢驗(yàn)流程完成后的結(jié)果;
  3. 由于移動(dòng)端場(chǎng)景區(qū)別于web令境,因此還需要考慮接口在各種常見場(chǎng)景下的設(shè)計(jì)杠园,例如重啟、進(jìn)程被回收舔庶、恢復(fù)出廠設(shè)置等等抛蚁;
  4. 由于移動(dòng)端資源較為有限,因此還需要關(guān)注接口在長(zhǎng)期執(zhí)行后的系統(tǒng)資源表現(xiàn)惕橙,例如cpu瞧甩、內(nèi)存等等;
  5. 其他

這里非常推薦設(shè)計(jì)之前借鑒一下騰訊移動(dòng)品質(zhì)中心(TMQ)寫的一篇接口測(cè)試用例設(shè)計(jì)【點(diǎn)我打開鏈接】的文章弥鹦,雖然不是特別針對(duì)framework層接口的肚逸,但基本思路總結(jié)的非常全面了。

用例編寫規(guī)范

基于junit框架進(jìn)行的接口測(cè)試是純代碼型的彬坏,不像普通的excel或者word文檔那樣天然具備良好的可讀性朦促,因此在用例管理和規(guī)范上,需要遵循一定的方式栓始。

  1. 用例名稱規(guī)則
  • 類名
    按照【Test】【測(cè)試對(duì)象】【場(chǎng)景】的結(jié)構(gòu)
    例如:
    測(cè)試softsim的性能务冕,類名可以為:TestSoftSimPerformance();
  • 方法名
    按照【test】【用例描述(測(cè)試目的)】的結(jié)構(gòu)
    例如:
    測(cè)試插拔sim卡幻赚,方法名可以為testPlugSimCard();
  • 注釋
    對(duì)于場(chǎng)景流程較長(zhǎng)或復(fù)雜的用例禀忆,建議增加注釋臊旭,用例內(nèi)容為步驟描述以及其他須注意點(diǎn)。
  1. 用例結(jié)構(gòu)設(shè)計(jì)規(guī)則
  • 單接口測(cè)試用例結(jié)構(gòu)設(shè)計(jì)
    單接口測(cè)試時(shí)箩退,建議盡量使用參數(shù)化的形式進(jìn)行測(cè)試离熏,以期減少測(cè)試用例代碼的冗余。
    詳細(xì)來說戴涝,我們推薦先把入?yún)⑦M(jìn)行歸類處理滋戳,在測(cè)試方法內(nèi)進(jìn)行分支判斷,然后使用@RunWith(Parameterized.class)注解裝飾測(cè)試類喊括,在測(cè)試類中通過@Parameterized.Parameters注解裝飾數(shù)據(jù)構(gòu)造方法胧瓜,給測(cè)試用例執(zhí)行矢棚。
  • 多接口組合測(cè)試用例結(jié)構(gòu)設(shè)計(jì)
    非單接口測(cè)試時(shí)郑什,測(cè)試用例的代碼設(shè)計(jì)結(jié)構(gòu)推薦按照分層測(cè)試的思想,即積木式的堆疊組合蒲肋,以期達(dá)到最大可復(fù)用狀態(tài)蘑拯。
    詳細(xì)來說,我們把a(bǔ)pi作為最小執(zhí)行單位兜粘,多個(gè)api之間關(guān)聯(lián)執(zhí)行的最小業(yè)務(wù)邏輯集合封裝為步驟(step)申窘,在step中,需要包含該業(yè)務(wù)邏輯或api調(diào)用后的基礎(chǔ)檢查點(diǎn)(Assert)孔轴;我們把step組合而成的業(yè)務(wù)邏輯封裝為testcase剃法,testcase中包含了該業(yè)務(wù)邏輯的最終檢查點(diǎn)。
    我們把testcase按照測(cè)試對(duì)象和場(chǎng)景歸類路鹰,歸屬到同屬性下作為一個(gè)測(cè)試類(TestClass)贷洲,由suite執(zhí)行器執(zhí)行。
  1. 用例文檔映射
    除了在代碼里要求的規(guī)范外晋柱,我們也需要(如果有余力的話)建立用例(代碼)和文檔的映射關(guān)系优构,這樣可以使得用例維護(hù)和執(zhí)行狀態(tài)等等更方便管理。
    一般而言雁竞,我們使用excel管理用例钦椭,在excel表格里,如普通case一樣的記錄碑诉,元素也和普通測(cè)試用例保持一致彪腔,例如用例編號(hào)、用例描述进栽、預(yù)期結(jié)果德挣、執(zhí)行結(jié)果等等;但是額外的再增加一列代碼映射關(guān)系泪幌,在這列里填上該條case在代碼工程里對(duì)應(yīng)的測(cè)試類和測(cè)試方法盲厌。

接口測(cè)試編碼常用工具

在編寫接口測(cè)試代碼的時(shí)候署照,不止是調(diào)用待測(cè)的接口,很多時(shí)候還需要自己寫方法提供測(cè)試參數(shù)或者測(cè)試環(huán)境吗浩,又或者需要和android的環(huán)境進(jìn)行交互建芙,下面闡述一下常用的編碼時(shí)用到的工具。

  1. 判斷系統(tǒng)狀態(tài)
    系統(tǒng)的狀態(tài)包括硬件狀態(tài)懂扼、系統(tǒng)屬性等等禁荸,大部分的狀態(tài)都可以通過android原始提供的方法如廣播、service阀湿、原生api等獲取赶熟,下面列舉幾個(gè)常用的狀態(tài)獲取,如果有更多不在其中的陷嘴,建議翻閱谷歌官方的android開發(fā)手冊(cè)映砖。
  • 判斷系統(tǒng)屏幕狀態(tài)
    判斷屏幕的息屏亮屏狀態(tài)可以使用廣播的形式,注冊(cè)一個(gè)系統(tǒng)廣播灾挨,示例代碼如下:
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        intentFilter=new IntentFilter();
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        intentFilter.addAction(Intent.ACTION_USER_PRESENT);
        mScreenReceiver=new ScreenBroadcastReceiver();
        registerReceiver(mScreenReceiver,intentFilter);
    }

    private class ScreenBroadcastReceiver extends BroadcastReceiver{
        private String action=null;
    
        @Override
        public void onReceive(Context context, Intent intent) {
            action=intent.getAction();
            if(Intent.ACTION_SCREEN_ON.equals(action)){
                Toast.makeText(context,"屏幕開屏",Toast.LENGTH_SHORT).show();
    
            }else if(Intent.ACTION_SCREEN_OFF.equals(action)){
                Toast.makeText(context,"屏幕關(guān)屏",Toast.LENGTH_SHORT).show();
            }else if(Intent.ACTION_USER_PRESENT.equals(action)){
                Toast.makeText(context,"屏幕解鎖",Toast.LENGTH_SHORT).show();
            }
        }
    }
    }
  • 判斷系統(tǒng)電池狀態(tài)
    判斷系統(tǒng)電池狀態(tài)可以直接使用BatteryManager.getLongProperty()獲取邑退,其入?yún)⑹且?guī)定的常量,主要有以下參數(shù):
    BATTERY_PROPERTY_CHARGE_COUNTER: 剩余電池容量劳澄,單位為微安時(shí)
    BATTERY_PROPERTY_CURRENT_NOW: 瞬時(shí)電池電流地技,單位為微安
    BATTERY_PROPERTY_CURRENT_AVERAGE: 平均電池電流,單位為微安
    BATTERY_PROPERTY_CAPACITY: 剩余電池容量秒拔,顯示為整數(shù)百分比
    BATTERY_PROPERTY_ENERGY_COUNTER: 剩余能量莫矗,單位為納瓦時(shí)
  • 獲取系統(tǒng)屬性
    獲取系統(tǒng)屬性可以直接通過android.os.SystemProperties獲取,示例代碼如下:
        private String getAndroidOsSystemProperties(String key) {
            String ret;
            try {
                systemProperties_get = Class.forName("android.os.SystemProperties").getMethod("get", String.class);
                ret = (String) systemProperties_get.invoke(null, key);
            } catch (Exception e) {
                return null;
            }
            return ret;
        }
    }
  • 其它...

2.模擬系統(tǒng)交互
在測(cè)試中往往需要模擬系統(tǒng)交互或者更改系統(tǒng)屬性砂缩,如模擬按鍵輸入作谚、模擬按鍵點(diǎn)擊、開啟設(shè)備節(jié)點(diǎn)等等梯轻;一般而言shell的執(zhí)行可以模擬大部分情況食磕,或者使用Instrumentation也可以達(dá)成目的,下面舉例幾個(gè)常見使用方式喳挑。

  • 執(zhí)行shell命令
    在android工程內(nèi)彬伦,可以通過Runtime.getRuntime().exec(shell命令)的方式直接執(zhí)行shell命令;因此可以利用這一點(diǎn)伊诵,通過shell模擬系統(tǒng)交互单绑,例如,通過shell發(fā)送keyevent曹宴,模擬按鍵操作搂橙、發(fā)送input text輸入文本等等。
  • 使用Instrumentation框架
    Instrumentation框架是是Android自帶一個(gè)單元測(cè)試框架笛坦,在這個(gè)框架下区转,你的測(cè)試應(yīng)用程序可以精確控制應(yīng)用程序苔巨。
    使用Instrumentation, 你可以在主程序啟動(dòng)之前废离,創(chuàng)建模擬的系統(tǒng)對(duì)象侄泽,如Context;控制應(yīng)用程序的多個(gè)生命周期蜻韭;發(fā)送UI事件給應(yīng)用程序悼尾;在執(zhí)行期間檢查程序狀態(tài)。 Instrumentation框架通過將主程序和測(cè)試程序運(yùn)行在同一個(gè)進(jìn)程來實(shí)現(xiàn)這些功能肖方。
    下面以模擬點(diǎn)擊按鍵示例闺魏,代碼如下:
    private void sendKeyCode(final int keyCode) throws InterruptedException {
        Thread t1 = new Thread () {
            public void run() {
                try {
                    Instrumentation inst = new Instrumentation();
                    inst.sendKeyDownUpSync(keyCode);
                } catch (Exception e) {
                    Log.e("Exception when sendPointerSync", e.toString());
                }
            }
        } ;
        t1.start();
        t1.join();
    }
  • 其它...

錯(cuò)誤記錄和分析

談及測(cè)試方法之后,當(dāng)然免不了對(duì)測(cè)試后問題的記錄和分析俯画,雖然往往最終的bug修復(fù)工作都是開發(fā)來做析桥,但我們?nèi)匀豢梢粤λ芗暗某袚?dān)問題前期分析工作。在android framework層的測(cè)試中活翩,除了用例本身的斷言提示烹骨,我們還要借助很多l(xiāng)og和工具進(jìn)行輔助分析翻伺,下面介紹一下這些材泄。

Android log日志類

Android環(huán)境中,存在各種各樣的log吨岭,下面介紹一下它們的用法拉宗。

logcat

logcat是最基礎(chǔ)的android log,基本上最常用的也是它辣辫,由于設(shè)備的緩沖區(qū)有限旦事,出了問題如果沒有及時(shí)的記錄就會(huì)被沖刷掉,一般而言急灭,我們會(huì)在測(cè)試開始前就開啟log輸出并轉(zhuǎn)儲(chǔ)到本地姐浮。

  • logcat存儲(chǔ)內(nèi)容
    logcat主要有四個(gè)緩沖區(qū),分別存儲(chǔ)了Radio:輸出通信系統(tǒng)的log葬馋、System:輸出系統(tǒng)組件的log卖鲤、Event:輸出event模塊的log、Main:所有java層的log畴嘶,以及不屬于上面3層的log蛋逾。
    由于我們往往是測(cè)試系統(tǒng)層api,因此一般這四個(gè)緩沖區(qū)都需要記錄下來窗悯。
  • logcat日志等級(jí)
    logcat一般分為V –Verbose(最低優(yōu)先級(jí))区匣、D – Debug、I – Info蒋院、W – Warning亏钩、E – Error莲绰、F – Fatal、S – Silen姑丑;排名越后優(yōu)先級(jí)越高钉蒲,在實(shí)際的分析里,我們可以優(yōu)先按照Fatal過濾日志查看彻坛。
  • logcat輸出記錄
    logcat可以直接通過adb命令輸出并記錄顷啼,例如“adb logcat -b radio -b main -b system -b events -b kernel -v time> E:%filename%”這樣的形式,如果想要特別只記錄測(cè)試時(shí)間段內(nèi)的數(shù)據(jù)昌屉,可以先執(zhí)行 “adb logcat -c”钙蒙,清除緩沖區(qū)日志。
traces.txt

在應(yīng)用發(fā)生anr時(shí)间驮,ActivityManagerService的appNotResponding方法就會(huì)被調(diào)用,然后在/data/anr/traces.txt文件中寫入ANR相關(guān)信息躬厌,因此對(duì)traces.txt的分析可以得出anr時(shí)的過程。

  • traces.txt存儲(chǔ)內(nèi)容
    traces.txt保存了發(fā)生ANR的進(jìn)程id竞帽、時(shí)間和進(jìn)程名稱等扛施;線程的調(diào)度信息、上下文信息屹篓、調(diào)用棧信息等疙渣;以及系統(tǒng)當(dāng)時(shí)的整體使用情況等。
  • traces.txt輸出記錄
    traces.txt可以直接通過adb命令輸出堆巧,日志默認(rèn)保存3天的信息妄荔,可以通過“adb pull data/anr/traces.txt d:\log”的形式拉取出來。
dmesg

dmesg是內(nèi)核的log信息谍肤。

  • dmesg存儲(chǔ)內(nèi)容
    dmesg是用來顯示內(nèi)核相關(guān)信息的啦租,它從內(nèi)核環(huán)形緩沖區(qū)中獲取數(shù)據(jù)的,主要存儲(chǔ)硬件相關(guān)的error和warning荒揣、守護(hù)進(jìn)程相關(guān)的信息篷角、系統(tǒng)的啟動(dòng)信息等等。
  • dmesg抓取方式
    dmesg可以直接通過adb命令輸出系任,例如“adb shell dmesg >D:/Kernel.log”這樣的形式恳蹲;或者直接執(zhí)行“adb shell”命令,在shell內(nèi)執(zhí)行“cat /proc/kmsg”赋除。
bugreport

bugreport是android上用于調(diào)試的阱缓、一個(gè)官方的調(diào)試信息聚合工具,它的內(nèi)容包含了多種調(diào)試信息举农。

  • bugreport存儲(chǔ)內(nèi)容
    bugreport包含了龐大的調(diào)試信息種類荆针,實(shí)際上他本身是個(gè)工具,作用就是對(duì)各種信息進(jìn)行聚合并形成一個(gè)統(tǒng)一文件;它包含了基本的logcat(包括各個(gè)緩沖區(qū))航背、vm trace喉悴、system property、系統(tǒng)資源情況(dumpsys checkin相關(guān)玖媚、dumpsys app相關(guān)等)箕肃、system server crash 和 system app crash 信息等等。
  • bugreport抓取方式
    bugreport可以直接通過adb命令抓取今魔,例如“adb bugreport > bugreport_out.txt”這樣的形式勺像。

  • bugreport讀取方式
    bugreport往往是個(gè)龐大的文件,直接讀的話可能會(huì)比較費(fèi)時(shí)错森,可以使用Google官方的開源分析工具bettery historian進(jìn)行分析吟宦,它會(huì)展現(xiàn)一個(gè)類似web的界面,更加簡(jiǎn)便易懂涩维。

coredump

coredump是linux原生的記錄系統(tǒng)產(chǎn)生異常的日志殃姓,一般在死機(jī)或者系統(tǒng)線程異常時(shí)記錄,需要說明的是瓦阐,并不是所有設(shè)備都有此日志蜗侈,需要開啟這個(gè)功能的日志才可以獲取到,而且存儲(chǔ)的方式和位置也是根據(jù)具體的實(shí)現(xiàn)方式而定的睡蟋,因此這里不多作介紹踏幻。

ramdump

ramdump指內(nèi)存轉(zhuǎn)儲(chǔ),也就是整個(gè)DRAM的運(yùn)行時(shí)內(nèi)容數(shù)據(jù)薄湿,當(dāng)系統(tǒng)發(fā)生崩潰性異常時(shí)候叫倍,通過一種機(jī)制實(shí)現(xiàn)將DRAM中的數(shù)據(jù)保存起來,保留了異巢蛄觯現(xiàn)場(chǎng),待離線分析用听诸。

  • ramdump存儲(chǔ)內(nèi)容
    ramdump中保留了異常時(shí)候的DRAM中的信息坐求,包括各種全局變量、局部變量晌梨、進(jìn)程狀態(tài)等等桥嗤。
  • ramdump抓取方式
    由于ramdump是死機(jī)(崩潰)時(shí)日志,因此一般無法通過adb獲取了仔蝌;我們可以直接通過高通平臺(tái)的qpst抓取泛领,方式也很簡(jiǎn)單,安裝qpst工具后敛惊,直接打開其下的QPST Configuration軟件渊鞋,在tab頁切換到Ports即可,發(fā)生死機(jī)(崩潰)后,機(jī)器重啟時(shí)锡宋,QPST會(huì)自動(dòng)抓取日志儡湾。

Android資源信息類

除了Android內(nèi)的各種日志類外,在我們進(jìn)行長(zhǎng)時(shí)間的測(cè)試類型例如壓力或者穩(wěn)定性測(cè)試的時(shí)候执俩,不止是產(chǎn)生錯(cuò)誤需要記錄分析徐钠,對(duì)被測(cè)接口整體的資源占用情況更需要記錄,這一塊也有多種方式實(shí)現(xiàn)役首,下面挑幾種常見的介紹尝丐。

Android Studio Profiler

如果是使用AS的方式進(jìn)行的app開發(fā)和接口測(cè)試,無疑AS自帶的Profiler頁是最為結(jié)合緊密的衡奥,在運(yùn)行測(cè)試之后摊崭,我們只需要切到在AS底部的Profiler頁,在SEESION欄選擇好需要監(jiān)控的進(jìn)程即可杰赛,一共分為四個(gè)可監(jiān)控項(xiàng)呢簸,分別是CPU、Memory乏屯、NETWORK根时、ENERGY。

Android Studio Profiler 只提供對(duì)資源信息的大致預(yù)覽辰晕,如果需要更細(xì)的分析蛤迎,需要dump相關(guān)的heap。

DDMS

DDMS是android sdk內(nèi)自帶的工具集含友,基本入口在sdk內(nèi)tools目錄下的monitor.bat替裆,雙擊該文件即可打開。

相比于Android Studio Profiler窘问,DDMS一般用于分析更細(xì)一層的東西辆童, 他可以實(shí)時(shí)的看到heap、threads惠赫、network的詳細(xì)使用情況把鉴; 并且在System Information內(nèi),可以看到cpu load儿咱、mermory usage庭砍、frame render的詳細(xì)分配情況;同樣混埠,它也支持把資源相關(guān)的heap文件dump下來詳細(xì)分析怠缸。

當(dāng)我們更進(jìn)一步的想要分析問題時(shí),可以使用DDMS钳宪。

ADB

adb是android調(diào)試協(xié)議橋的簡(jiǎn)稱揭北,除了上面提到的可以記錄log之外扳炬,也有很多命令可以查看資源使用情況;例如獲取應(yīng)用的堆內(nèi)存文件“
adb shell am dumpheap <packagename> /data/local/tmp/name.hprof”罐呼、獲取應(yīng)用的線程文件“
adb shell run-as <packagename> kill -3 pid adb pull /data/anr/traces.txt”等等鞠柄,更多用法,可以自行百度嫉柴。

第三方監(jiān)控工具(平臺(tái))

除了android生態(tài)內(nèi)自帶的工具集外厌杜,有很多大廠也開源了他們的資源監(jiān)控方案,例如騰訊的GT计螺、訊飛的Itest夯尽、螞蟻金服的SoloPi等等,他們往往也都兼具了基本的資源監(jiān)控登馒,例如cpu匙握、內(nèi)存、fps陈轿、電量圈纺、溫度、網(wǎng)絡(luò)上下行等等麦射;甚至可以進(jìn)行簡(jiǎn)單的壓力模擬蛾娶,例如內(nèi)存填充、cpu壓力模擬等等潜秋。

如果對(duì)android生態(tài)內(nèi)工具不熟悉的話蛔琅,建議直接使用這些,更為簡(jiǎn)便易上手峻呛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末罗售,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钩述,更是在濱河造成了極大的恐慌寨躁,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件切距,死亡現(xiàn)場(chǎng)離奇詭異朽缎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谜悟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來北秽,“玉大人葡幸,你說我怎么就攤上這事『孛ィ” “怎么了蔚叨?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蔑水,道長(zhǎng)邢锯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任搀别,我火速辦了婚禮丹擎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歇父。我一直安慰自己蒂培,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布榜苫。 她就那樣靜靜地躺著护戳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垂睬。 梳的紋絲不亂的頭發(fā)上媳荒,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音驹饺,去河邊找鬼钳枕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛逻淌,可吹牛的內(nèi)容都是我干的么伯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼卡儒,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼田柔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起骨望,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤硬爆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后擎鸠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缀磕,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年劣光,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了袜蚕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绢涡,死狀恐怖牲剃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情雄可,我是刑警寧澤凿傅,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布缠犀,位于F島的核電站,受9級(jí)特大地震影響聪舒,放射性物質(zhì)發(fā)生泄漏辨液。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一箱残、第九天 我趴在偏房一處隱蔽的房頂上張望滔迈。 院中可真熱鬧,春花似錦疚宇、人聲如沸亡鼠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽间涵。三九已至,卻和暖如春榜揖,著一層夾襖步出監(jiān)牢的瞬間勾哩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工举哟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留思劳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓妨猩,卻偏偏與公主長(zhǎng)得像潜叛,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子壶硅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容