1. 程式人生 > >app效能測試與弱網測試

app效能測試與弱網測試

1. 效能測試

  • Android的app效能測試包括的測試項比如:  1、資源消耗  2、記憶體洩露  3、電量功耗  4、耗時  5、網路流量消耗  6、移動終端相關資源利用率  7、幀率  8、渲染等等....

  • 測試方法:  1、設計場景 :手工或自動化場景  2、獲取資料:可獲取的資料包括:記憶體、cpu、電量功耗、hprof(記憶體洩露分析檔案)、響應時間等等。。。。配合手工或自動化場景來獲取資料(最好多取幾次而且每次配合不同的裝置看平均值)作為最後的對比分析  3、結果分析 :拿到資料後分析哪些模組的資料異常再去Check code定位問題的原因

  • Android系統的幾種場景狀態:  1、空閒狀態: 指開啟應用後,點選home鍵讓應用後臺執行,此時應用處於的狀態叫做空閒  2、中等規格和滿規格狀態:中等規格和滿規格指的是對應用的操作時間的間隔長短不一,中等規格時間較長,滿規格時間較短

1.1 記憶體篇

背景知識:  C/C++申請的記憶體空間在native heap中,而java申請的記憶體空間則在dalvik heap中。這個是因為Android系統對dalvik的vmheapsize作了硬性限制,當java程序申請的java空間超過閾值時,就會丟擲OOM異常(這個閾值可以是48M、24M、16M等,視機型而定),可以通過adb shell getprop | grep dalvik.vm.heapgrowthlimit檢視此值。也就是說,程式發生OMM並不表示RAM不足,而是因為程式申請的java heap物件超過了dalvik vmheapgrowthlimit。也就是說,在RAM充足的情況下,也可能發生OOM。

這樣的設計似乎有些不合理,但是Google為什麼這樣做呢?這樣設計的目的是為了讓Android系統能同時讓比較多的程序常駐記憶體,這樣程式啟動時就不用每次都重新載入到記憶體,能夠給使用者更快的響應。迫使每個應用程式使用較小的記憶體,移動裝置非常有限的RAM就能使比較多的app常駐其中。但是有一些大型應用程式是無法忍受vmheapgrowthlimit的限制的

實際上dalvik.vm.heapgrowthlimit和dalvik.vm.heapsize都是java虛擬機器的最大記憶體限制,應用如果不想在dalvikheap達到heapgrowthlimit限制的時候出現OOM,需要在Manifest中的application標籤中宣告android:largeHeap=“true”,聲明後應用dalvik heap達到heapsize的時候才會出現OOM

  1. 記憶體測試中的測試子項:  1)空閒狀態下的應用記憶體消耗情況  2)中等規格狀態下的應用記憶體消耗情況  3)滿規格狀態下的應用記憶體消耗情況  4)應用記憶體峰值情況  5)應用記憶體洩露情況  6)應用是否常駐記憶體  7)壓力測試後的記憶體使用情況

  2. 記憶體問題現象:  1)記憶體抖動  2)大記憶體物件被分配  3)記憶體不斷增長  4)頻繁GC

  3. 記憶體資料獲取:  1、各種linux命令(top、free、meminfo…)  2、通過dumpsys adb shell dumpsys meminfo [pakagename | pid]  3、通過/system/xbin/procrank工具 adb shell procrank  說明:  VSS – Virtual Set Size 虛擬耗用記憶體(包含共享庫佔用的記憶體)  RSS – Resident Set Size 實際使用實體記憶體(包含共享庫佔用的記憶體)  PSS – Proportional Set Size 實際使用的實體記憶體(比例分配共享庫佔用的記憶體)  USS – Unique Set Size 程序獨自佔用的實體記憶體(不包含共享庫佔用的記憶體) USS 是針對某個程序開始有可疑記憶體洩露的情況,是一個程式啟動了會產生的虛擬記憶體,一旦這個程式程序殺掉就會釋放。不過USS需要通過root的手機。一般沒有root的手機我們可以獲取PSS。而PSS通過如下命令來獲取:adb shell dumpsys meminfo <Package Name>|grep TOTAL  4、通過android提供的procrank  1)首先去google獲取procrank、procmem、libpagemap.so三個檔案  2)然後push檔案,執行 adb push procrank /system/xbin adb push procmem  /system/xbin adb push libpagemap.so /system/lib  3)賦權 adb shell chmod 6755 /system/xbin/procrank adb shell chmod 6755 /system/xbin/procmem adb shell chmod 6755 /system/lib/libpagemap.so ,  4)在開啟工具記錄 adb shell procrank |grep packagename >/address/procrank.txt  5、通過android提供的ActivityManager的getMemoryInfo(ActivityManager.MemoryInfo outInfo)(這個方法是寫一個簡單的app去監控的時候用到的,輕便簡單)

  1. private void GetMemory()
  2. {
  3. final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
  4. ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
  5. activityManager.getMemoryInfo(info);
  6. Log.i(tag,"系統剩餘記憶體:"+(info.availMem >> 10)+"k");
  7. Log.i(tag,"系統是否處於低記憶體執行:"+info.lowMemory);
  8. Log.i(tag,"當系統剩餘記憶體低於"+info.threshold+"時就看成低記憶體執行");
  9. }
  1. 6、Memory Monitor (android studio的外掛) 【makedown???】

  2. 4. /proc/meminfo檔案裡列出的欄位解釋:

MemTotal: 所有可用RAM大小。 MemFree: LowFree與HighFree的總和,被系統留著未使用的記憶體。  Buffers: 用來給檔案做緩衝大小。 Cached: 被高速緩衝儲存器(cache memory)用的記憶體的大小(等於diskcache  minus SwapCache)。 SwapCached:被高速緩衝儲存器(cache  memory)用的交換空間的大小。已經被交換出來的記憶體,仍然被存放在swapfile中,用來在需要的時候很快的被替換而不需要再次開啟I/O埠。  Active: 在活躍使用中的緩衝或高速緩衝儲存器頁面檔案的大小,除非非常必要,否則不會被移作他用。 Inactive:  在不經常使用中的緩衝或高速緩衝儲存器頁面檔案的大小,可能被用於其他途徑。 SwapTotal: 交換空間的總大小。 SwapFree:  未被使用交換空間的大小。 Dirty: 等待被寫回到磁碟的記憶體大小。 Writeback: 正在被寫回到磁碟的記憶體大小。  AnonPages:未對映頁的記憶體大小。 Mapped: 裝置和檔案等對映的大小。 Slab:  核心資料結構快取的大小,可以減少申請和釋放記憶體帶來的消耗。 SReclaimable:可收回Slab的大小。  SUnreclaim:不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)。  PageTables:管理記憶體分頁頁面的索引表的大小。 NFS_Unstable:不穩定頁表的大小。

5. android檢查記憶體洩露步驟:

1、執行Monkey進行壓力測試: adb shell monkey -p cn.microinvestment.weitou --pct-touch 100 --ingore-crashes --throttle 1000 -s 100 -v -v 50 2、監控記憶體值,如果出現過大等遞增異常則儲存HPROF檔案(hprof檔案是Java 虛擬機器的Heap快照)用於分析檢視應用記憶體的命令: adb shell dumpsys meminfo cn.microinvestment.weitou(程序名)  如果發現記憶體過大,則儲存HPROF檔案:adb shell am dumpheap <程序名> <儲存路徑>  3、分析hprof檔案  用工具MAT來檢視,首先還要這個HPROF檔案轉換成MAT可讀的檔案  在Android SDK tool裡面有個hprof-conv命令:  hprof-conv <原HPROF檔案路徑> <轉換後的HPROF路徑> hprof-conv a.hprof b.hprof  4、用MAT工具開啟轉換後的HPROF檔案  一般選擇Leak Suspects Report(通過SQL語句來查詢物件有沒有被釋放掉,如果有多個相同的物件,則會存在記憶體洩露的問題)

1.2 CPU篇

  1. CPU測試中的測試子項:  1)空閒狀態下的應用CPU消耗情況  2)中等規格狀態下的應用CPU消耗情況  3)滿規格狀態下的應用CPU消耗情況  4)應用CPU峰值情況

  2. CPU資料獲取:  1)adb shell dumpsys cpuinfo | grep packagename  2)top命令 adb shell top -m 10 -s cpu #檢視佔用cpu最高的前10個程式(-t 顯示程序名稱,-s 按指定行排序,-n 在退出前重新整理幾次,-d 重新整理間隔,-m 顯示最大數量) adb shell top | grep PackageName > /address/cpu.txt

1.3 流量篇

  1. 概念:  中等負荷:應用正常操作  高負荷:應用極限操作

  2. 流量測試中的測試子項:  1、應用首次啟動流量值  2、應用後臺連續執行 2 小時的流量值  3、應用高負荷執行的流量峰值  4、應用中等負荷執行時的流量均值

  3. 獲取流量資料:  1、tcpdump+wireshark  2、/proc/net/目錄下相關檔案  cat /proc/net/dev 獲取系統的流量資訊  3、查詢應用的pid: adb shell ps | grep tataufo #如:31002  通過PID獲取該應用的流量資料: adb shell cat /proc/31002/net/dev  (wlan0代表wifi上傳下載量標識, 單位是位元組可以/1024換算成KB, 開啟手機飛航模式再關掉就可以將wlan0中的值初始化0)  4、查詢應用的pid: adb shell ps | grep tataufo #如:31002  通過PID獲取UID:adb shell cat /proc//status  通過UID獲取:adb shell cat /proc/net/xt_qtaguid/stats | grep 31002  5、通過adb shell dumpsys package來獲取應用的uid資訊,然後在未操作應用之前,通過檢視 :  adb shell cat /proc/uid_stat/uid/tcp_rcv  adb shell cat /proc/uid_stat/uid/tcp_snd  獲取到應用的起始的接收及傳送的流量,然後我們再操作應用,再次通過上述2條命令可以獲取到應用的結束的接收及傳送的流量,通過相減及得到應用的整體流量消耗  6、Android程式碼:Android的TrafficStats類

1.4 功耗篇

  1. 功耗測試中的測試子項:  1、手機安裝目標APK前後待機功耗無明顯差異  2、常見使用場景中能夠正常進入待機,待機電流在正常範圍內  3、長時間連續使用應用無異常耗電現象

  2. 功耗測試方法:  方法一:軟體  1、採用市場上提供的第三方工具,如金山電池管家之類的。  2、就是自寫工具進行,這裡一般會使用3種方法:  1)基於android提供的PowerManager.WakeLock來進行  2)比較複雜一點,功耗的計算=CPU消耗+Wake lock消耗+資料傳輸消耗+GPS消耗+Wi-Fi連線消耗  3)通過 adb shell dumpsys battery來獲取  3、battery-historian(google開源工具)  方法二:硬體  一般使用萬用表或者功耗儀安捷倫進行測試,使用功耗儀測試的時候,需要製作假電池來進行的,有些不能拔插電池的手機還需要焊接才能進行功耗測試

1.5 GPU篇(FPS)

  1. 概念:  過度繪製: 介面顯示的activity套接了多層而導致  幀率:螢幕滑動幀速率  幀方差: 螢幕滑動平滑度  **FPS:**Frames Per Second 每秒顯示的幀數 根據人眼的生理結構,幀率高於24時就被認為是連貫的。對於遊戲畫面30fps是最低能接受的,60fps逼真感,如果幀率高於螢幕重新整理頻率就是浪費。要達到30fps,每幀所佔用的時間要小於33毫秒

  2. GPU測試中的測試子項:  1、介面過度繪製  2、螢幕滑動幀速率  3、螢幕滑動平滑度

  3. 過度繪製測試:(人工進行測試)  開啟開發者選項中的顯示GPU過度繪製(Debug GPU overdraw)  驗收的標準:  1、不允許出現黑色畫素  2、不允許存在4x過度繪製  3、不允許存在面積超過螢幕1/4區域的3x過度繪製(淡紅色區域)

  4. 螢幕滑動幀速率測試:  方法一:  1.手機端開啟開發者選項中的啟用跟蹤後勾選Graphics和View  2.啟動SDK工具Systrace,勾選被測應用,點選Systrace,在彈出的對話方塊中設定持續抓取時間,在trace taps下面勾選gfx及view選項  3.手工滑動介面可以通過節拍來進行滑動或者掃動,幀率資料會儲存到預設路徑下,預設名稱為trace.html  4.將trace.html檔案拷貝到linux系統下通過命令進行轉換,生成trace.csv檔案  grep 'postFramebuffer' trace.html | sed -e 's/.]\W//g' -e 's/:.*$//g' -e 's/.//g' > trace.csv  5.用excel開啟檔案計算得到幀率  方法二:  硬體的方法,開啟高速相機,開啟攝像模式,錄製手工滑動或者掃動被測應用的視訊,再通過人工或者程式數幀的方法對結果進行計算得到幀率

  5. 螢幕滑動平滑度的測試:  方法如同幀率測試,唯一的差異就是最後的結果計算公式的差異

  6. 捕獲app幀率(android流暢度FPS測試):  1、開啟手機開發者選項,勾選GPU顯示配置檔案(系統會記錄保留每個介面最後128幀影象繪製的相關時間資訊)  2、adb shell dumpsys gfxinfo com.xxx.xxx > zinfo.txt  3、結果資料分析  Profile data in ms部分:  Draw: 建立顯示列表的時間(DisplayList),所有View物件OnDraw方法佔用的時間  Process: Android 2D渲染引擎執行顯示列表所花的時間,View越多時間越長  Execute:將一幀影象交給合成器(compsitor)的時間,較小

  7. 其他工具:  GameBench 測試android app的FPS工具  Gfxinfo 檢視app繪製效能工具

1.6 響應時間篇

  1. 理解:  1)從單擊事件觸發到容器啟動NativeAPP消耗的時間(埋點)  2)NativeAPP完整啟動消耗的時間(可以通過system.log獲取)  3)Native呼叫RPC請求方法的延遲時間(埋點)  4)RPC請求發出去過程中的具體資料(req_size req_header req_time等,通過埋點獲取)  5)RPC請求返回的具體資料(res_size res_header res_time等,通過埋點獲取)  6)本地解析返回資料所消耗的時間(埋點或者TraceView工具可獲取)  7)介面渲染的時間(可以通過慢速攝像機或者埋點獲取)

  2. 應用的啟動時間的測試,分為三類:  1)首次啟動 --應用首次啟動所花費的時間  2)非首次啟動 --應用非首次啟動所花費的時間  3)應用介面切換--應用介面內切換所花費的時間

  3. 應用啟動時間資料獲取:  1、adb logcat > /address/logcat.txt #所有activity列印的日誌 find “Displayed” /address/logcat.txt > /newaddress/fl.txt #通過日誌過濾關鍵字Displayed來過濾 find “ActivityName” /newaddress/fl.txt > /newaddress/last.txt #通過activity名來過濾獲取所測應用  通過計算activity最後剩餘的時間之和即可  2、硬體測試, 使用高速相機或者手機採用錄影的方法把應用啟動過程給錄製下來,然後通過人工數幀或者程式數幀的方式計算啟動時間

2 弱網測試

  1. 測試方法:  1、使用真實的SIM卡、運營商網路來進行測試(移動無線測試中存在一些特別的BUG必須在特定的真實的運營商網路下才會發現)  2、通過代理的方式模擬弱網環境進行測試(charles 硬延遲)  3、連線模擬弱網的熱點進行測試

  2. 熱點模擬方法:  1)通過設定iPhone的開發者模式之後共享熱點(硬延遲)  2)FaceBook開源的ATC(可使用樹莓派來搭建ACT環境)

  3. 使用者體驗需要做的:  1)在應用中統一弱網載入的介面樣式、動畫效果、菊花icon等  2)統一網路錯誤、服務端錯誤、超時等展現給使用者的介面和提示語句  3)定義清楚在每個中間過程是的使用者互動行為