?移動應用常見性能指標
? 要對應用開展性能測試,首先需要了解需要重點關注哪些指標?指標的參考范圍大致是多少?可采用哪些工具收集這些指標?如何收集?如果指標有異常,大致有哪些high level的優化思路。這篇博客從cpu,內存,網絡,其他,四個方面整理了移動應用常見指標以及參考值范圍。具體如下圖所示:(需要注意:指標數據范圍僅供參考,以內存占用大小為例,國內很多app,實際應用大小都超過了200MB)
如何用Android Studio Profile分析應用性能
? 使用Android studio上運行移動應用,在工具最下面,會自動顯示Profile工具菜單,如果沒有看到這個菜單,還可以通過View/Tool Windows/中選擇Profile工具。選擇虛擬設備,以及選擇應用后,就可以通過profile觀察應用消耗的cpu,內存等信息了。
? 除了Android Profiler,還可以使用App Inspector觀察應用的網絡請求情況,數據庫連接情況,后臺任務情況等信息。通過收集這些信息進行性能評估。
? 在Android studio上還可以連接Firebase觀察crash情況。在App Quality Inspect菜單中,選擇Firebase,安裝FireBase官網給出的配置建議完成配置后,即可通過FireBase觀察應用Crash情況。
? 除了上面的性能數據收集分析工具,在Android studio中還可以查看logcat日志,查看應用運行過程中的異常信息,可幫助開發更好的進行分析。Android studio上的工具總體來將大部分都是白盒層面的工具,除了這些工具,實際還可以通過第三方黑盒類工具進行性能數據收集和分析。
如何用charles、wireshark等分析網絡情況
? 如果要使用工具對移動應用進行抓包,大致可以分為三個步驟。步驟一:在工具上設置代理端口以及bypass的URL,這樣所有通過這個端口的流量都會轉發到代理工具上。步驟二:保證移動應用和電腦連接到相同的wifi上,這樣可以保證通過內部IP地址訪問時,可以相互訪問,在手機上將電腦的內部IP地址+工具的代理端口設置為手機的代理,這樣所有經過手機的流量,實際都會轉發到電腦上安裝的代理工具上。步驟三:下載證書,并在手機上信任證書,這樣https的請求才能被解碼顯示。下面以charls和fidder為例子,簡要演示如何通過抓包工具抓取移動手機上http/https請求。
步驟一:代理端口和規則設置
下面是Fidder的connections菜單的設置,這里代理的端口是8866,enable“Allow remote devices to connect”,Bypass URLs中增加了*,即所有的請求都被代理轉發。
如果選用Charles來抓包,charles的默認端口是8888,這里也需要配置SSL proxying,增加了*,即所有的請求都被抓取并轉發。
步驟二:移動手機上手動設置代理
在手機上設置代理前,首先需要知道電腦的內網IP,這個IP可以從代理工具上獲取,以charles為例,在help菜單下,點擊“Install Charles Root certification on a Mobile Device”,即可顯示電腦的內網IP地址,當然,你也可以通過ifconfig命令獲取IP地址。
? 在移動手機的wifi菜單下,手動設置代理的IP地址的端口,如下圖所示:這里用的是Fidder的代理地址信息。設置代理后,所有的手機上的流量就能被抓包工具獲取,并進行轉發。
步驟三:下載安裝證書,并信任證書
? 代理設置后,就可以按工具的提示信息,到指定web地址上下載證書,下載后安裝,并信任證書。以Android手機為例,設置-安全-更多安全設置-加密與憑據-安裝證書,選擇剛才通過網站下載的證書,即可進行安裝。安裝完成后,在該目錄還有個用戶憑證的菜單,進入查看確保剛才的證書已經添加進去了。(需要注意一點:必須先設置代理,到chls.pro/ssl地址上才能下載證書。其他抓包工具如Fidder,HTTP toolkit等也是相同的步驟)
? 安裝證書后,即可開始用Fidder或者Charls進行抓包了。在手機上訪問移動app或者在瀏覽器上訪問網站,在工具中會顯示所有的https/http請求信息。下圖是Fidder中抓取到的http請求信息,可以看到里面包含了整個請求耗費的時間,以及分段時間(即DNS time/TCP connect Time/HTTPS Handshake Time等),除時間外,還包括包的大小信息,通過這些信息,可以有效進行性能分析。
? 當然,除了Fidder,Charles也同樣可以獲取到https/http請求的時間,包大小等信息。具體如下所示:
? 對于https請求,為什么charles等工具可以進行解碼呢?Charles和類似的中間人(Man-in-the-Middle, MITM)代理工具能夠解密 HTTPS 請求的原因在于它們能夠扮演客戶端和服務器之間的中間人角色,通過安裝自簽名根證書來實現。以下是詳細的解釋其工作原理和具體步驟:
? Charles 生成一個自簽名的根證書,并要求用戶在其設備上安裝并信任這個根證書。當 Charles 代理 HTTPS 請求時,它會在客戶端和目標服務器之間建立兩個獨立的 SSL/TLS 連接。對于每一個客戶端請求,Charles 生成一個與目標服務器對應的偽造證書,這個偽造證書是用 Charles 的自簽名根證書簽名的。
? Charles 與客戶端建立 SSL/TLS 連接,并將自己偽裝成目標服務器。因為客戶端信任 Charles 的根證書,所以它會信任這個偽造的服務器證書。
? 同時,Charles 與目標服務器建立另一個 SSL/TLS 連接,并使用服務器的真實證書進行通信。Charles 代理解密從客戶端發送到服務器的加密數據,然后將其轉發到目標服務器。同樣地,它解密從服務器返回到客戶端的加密數據,再將其轉發回客戶端。
? 當然,如果請求數據是應用層加密的,Charles 或其他類似的工具無法直接解密這些內容。你需要應用本身的密鑰和算法來解密,這通常是不可能的,因為這些信息對于普通用戶來說是不可訪問的。例如,抓取weixin的包,是無法看到包的request具體內容的,應該是weixin進行了請求數據層面的再次加密。
? charles和fidder主要是抓取https/http請求,如果要對網絡進行更加細致的分析,需要配合wireshark,wireshark是一個開源的抓包分析工具,對于https請求,wireshark不支持自動解密操作,這個部分可以用charles或者fidder解決。當開啟了charles或者fidder一類的工具后,因為移動手機上的所有流量都會經過代理工具,所以開啟wireshark,選擇以太網端口抓取流量,即可抓取電腦上所有流量,再通過在過濾器中設置過濾來查看需要的分析的包信息。啟動wireshark(這里為了不會有權限問題,使用sudo命令啟動應用:sudo /Applications/Wireshark.app/Contents/MacOS/Wireshark)。在filter中通過設置ip地址為移動手機地地址來篩選出移動手機上的所有請求,然后進行分析。
? 當然,除了啟動代理工具,來讓wireshark抓取移動手機上流量包外,還可以在電腦上開啟熱點,手機連接到熱點網絡上,在啟動wireshark時選擇熱點網路,也可以實現抓取移動手機上流量的效果。
如何用UIAutomator2進行巡檢
? 除了上面的性能數據收集工具,還可以使用Android提供的UIAutomator2工具編寫巡檢代碼。自動檢查某些關鍵操作是否在期望時間內完成。例如,這里假設期望的所有操作都能在200ms內完成,下面代碼調用Android提供的uiautomator2框架,對應用的一些需要檢查的元素進行操作,并判斷耗費的時間,將生成的結果存儲到巡檢報告文件中。為了測試更加穩定,也可以多次操作,求平均值,如果平均值在200ms內即可。
import uiautomator2 as u2
import time# 連接設備
d = u2.connect()# 定義關鍵元素的資源ID或其他屬性
elements_to_check = [{"resourceId": "com.example:id/button1"},{"resourceId": "com.example:id/button2"},{"resourceId": "com.example:id/input_field"},{"resourceId": "com.example:id/submit_button"}
]def check_operation_timing(element):# 開始計時start_time = time.time()# 執行操作try:el = d(**element)if el.exists:el.click()else:print(f"元素 {element} 不存在")return False, 0except Exception as e:print(f"操作失敗: {e}")return False, 0# 結束計時end_time = time.time()# 計算響應時間response_time = (end_time - start_time) * 1000 # 轉換為毫秒# 檢查響應時間是否在200ms以內if response_time <= 200:print(f"操作成功,響應時間:{response_time:.2f} 毫秒")return True, response_timeelse:print(f"操作超時,響應時間:{response_time:.2f} 毫秒")return False, response_timedef perform_inspection(elements):response_times = []for element in elements:success, response_time = check_operation_timing(element)if success:response_times.append(response_time)time.sleep(0.5) # 添加一些延遲,以避免設備過載return response_times# 進行巡檢
response_times = perform_inspection(elements_to_check)# 統計結果
if response_times:average_time = sum(response_times) / len(response_times)print(f"平均響應時間:{average_time:.2f} 毫秒")
else:print("沒有成功的操作")# 處理巡檢結果,例如,保存到文件或數據庫
? 以上就是在進行移動應用性能測試分析時,需要關注的常用指標以及一些常用工具的使用。