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)容的,因此材义,我們首先解決本地的編譯問題均抽。
一般來說,有兩種方法:
- 由開發(fā)直接提供給你接口方法所在的jar包其掂,你在需要調(diào)用的地方引用該jar包油挥,直接調(diào)用jar包內(nèi)開發(fā)好的接口;
- 開發(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)證接口:
- 在開發(fā)的app內(nèi)殉簸,采用界面ui形式闰集,例如提供表單和按鈕沽讹,來進(jìn)行接口參數(shù)的輸入和驗(yàn)證,這個(gè)途徑一般用于給功能測(cè)試人員返十,進(jìn)行快速簡(jiǎn)單的驗(yàn)證妥泉,或者充當(dāng)工具的角色椭微,通過調(diào)用接口快速開啟系統(tǒng)提供的某種功能洞坑;
- 在開發(fā)的app內(nèi),預(yù)留廣播蝇率,這樣可以通過外部shell發(fā)送廣播來調(diào)起相關(guān)的接口迟杂,而無需在界面打開;這個(gè)途徑一般用于給其他類型的自動(dòng)化測(cè)試提供接口的使用途徑本慕;
- 是借用android的單元測(cè)試框架排拷,android junit,直接在代碼層進(jìn)行接口測(cè)試锅尘。
使用junit進(jìn)行framework層接口測(cè)試
下面主要說一下如何用junit進(jìn)行framework層的接口測(cè)試监氢。
測(cè)試工程搭建
- 新建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í)行)。
- 集成待測(cè)接口
新建完Android應(yīng)用工程后璧榄,我們需要把我們自己開發(fā)或者修改的framework接口集成在工程內(nèi)方便測(cè)試時(shí)調(diào)用特漩;這里就使用上面介紹的兩種方法,即新建待測(cè)試接口同名的類/方法骨杂,或者直接引用sdk(jar)包調(diào)用涂身。
- 新建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è)方向考慮:
- 單接口的各種正反向接口參數(shù)輸入吏夯,對(duì)比接口設(shè)計(jì)文檔檢驗(yàn)輸出;
- 接口之間組合成業(yè)務(wù)流即横,形成各種正反向業(yè)務(wù)場(chǎng)景噪生,對(duì)比需求文檔檢驗(yàn)流程完成后的結(jié)果;
- 由于移動(dòng)端場(chǎng)景區(qū)別于web令境,因此還需要考慮接口在各種常見場(chǎng)景下的設(shè)計(jì)杠园,例如重啟、進(jìn)程被回收舔庶、恢復(fù)出廠設(shè)置等等抛蚁;
- 由于移動(dòng)端資源較為有限,因此還需要關(guān)注接口在長(zhǎng)期執(zhí)行后的系統(tǒng)資源表現(xiàn)惕橙,例如cpu瞧甩、內(nèi)存等等;
- 其他
這里非常推薦設(shè)計(jì)之前借鑒一下騰訊移動(dòng)品質(zhì)中心(TMQ)寫的一篇接口測(cè)試用例設(shè)計(jì)【點(diǎn)我打開鏈接】的文章弥鹦,雖然不是特別針對(duì)framework層接口的肚逸,但基本思路總結(jié)的非常全面了。
用例編寫規(guī)范
基于junit框架進(jìn)行的接口測(cè)試是純代碼型的彬坏,不像普通的excel或者word文檔那樣天然具備良好的可讀性朦促,因此在用例管理和規(guī)范上,需要遵循一定的方式栓始。
- 用例名稱規(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)。
- 用例結(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í)行。
- 用例文檔映射
除了在代碼里要求的規(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í)用到的工具。
- 判斷系統(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)便易上手峻呛。