APP性能(Monkey)【啟動時間、CPU、流量、電量、內存、FPS、過度渲染】


APP性能測試—啟動時間

冷啟動—程序完全關閉時的啟動

啟動:adb shell am start -W -n package/activity

停止:adb shell am force-stop package

熱啟動—程序退到后台,並未完全殺死時的啟動

啟動:adb shell am start -W -n package/activity

停止:adb shell input keyevent  3 3表示點擊手機上的back

【啟動時間】數據分析

1、取一個啟動時間的平均值(如果運行10次,一般把第1次去掉。取后面9次的數據)

2、畫一個曲線圖

3、怎么確定我們的啟動時間是否正常?可以和市場上的同類產品的平均值對比,也可以和 自己的APP歷史版本對比

【啟動時間】性能測試腳本

 

#coding:utf8
import os,time,csv

#APP類
class App(object):
    def __init__(self):
        self.content=""
        self.startTime="0"
        
    #啟動APP com.android.browser/.BrowserActivity
    def LaunchApp(self):
        cmd='adb shell am start -W -n package/activity'
        self.content=os.popen(cmd) #執行cmd,並將執行結果賦值給變量 content
    
    #測試冷啟動和熱啟動APP的區別在於停止方法
    #停止APP,用於冷啟動的APP
    def StopApp(self):
        cmd='adb shell am force-stop package'
        os.popen(cmd) #執行cmd
        
    #停止APP,用於熱啟動的APP
    # def StopApp(self):
        # cmd='adb shell input keyevent 3'#觸發手機上的back鍵,實現退出
        # os.popen(cmd) #執行cmd
    
        
    #獲取啟動時間
    def GetLaunchedTime(self):
        for line in self.content.readlines():
            if "ThisTime" in line:
                self.startTime=line.split(":")[1]
                break
        return self.startTime
    
#控制類
class Controller(object):
    def __init__(self,count):
        self.app=App()
        self.count=count
        self.alldata=[("timestamp","elapsedtime")]
        
    #單次測試過程
    def testprocess(self):
        self.app.LaunchApp()
        time.sleep(5)
        elapsedtime=self.app.GetLaunchedTime()
        self.app.StopApp()
        time.sleep(3)
        currentTime=self.getCurrentTime()
        #將時間戳存到數組里
        self.alldata.append((currentTime,elapsedtime))
        
    #多次執行測試過程。用while循環,現在__init__里定義執行次數的參數,每執行一次,自減1 直到完成
    def run(self):
        while self.count>0:
            self.testprocess()
            self.count-=1
            
    #獲取當前的時間戳
    def getCurrentTime(self):
        currentTime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
        return currentTime
            
    #數據的存儲
    def SaveDataToCSV(self):
        csvfile=file('startTime.csv','wb')
        write=csv.write(csvfile)
        #將alldata的數據寫入write
        write.writerows(self.alldata)
        csvfile.close()
    
if __name__=='__main__':
    #實例化
    controller=Controller(10)
    #調用run方法
    controller.run()
    #調用SaveDataToCSV方法
    controller.SaveDataToCSV()

 

APP性能測試—CPU

獲取CPU數據:adb shell dumpsys cpuinfo | grep package

【CPU】數據分析

可以配合操作腳本加上監控命令去測試CPU,這樣更接近實際使用情況.如果CPU使用率一直上升,沒有下降.或者達到100%/80% 等等,就說明有問題了

【CPU】性能測試腳本

#coding:utf8
import csv,os,time

#控制類
class Controller(object):
    def __init__(self,count):
        self.counter=count
        self.alldata=[('timestamp','cpustatus')]
        
    #單次測試過程
    def testprocess(self):
        result=os.popen("adb shell dumpsys cpuinfo | grep package")
        for line in result.readlines():
            cpuvalue=line.split('%')[0]
            
        currenttime=self.getCurrentTime()
        self.alldata.append((currenttime,cpuvalue))
        
    #多次執行測試過程
    def run(self):
        while self.counter>0:
            self.testprocess()
            self.counter=self.counter-1
            time.sleep(5)
            
    #獲取當前的時間戳
    def getCurrentTime(self):
        currentTime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
        return currentTime
        
    #數據的存儲
    def saveDataCSV(self):
        csvfile=file('cpustatus.csv','wb')
        writer=csv.writer(csvfile)
        writer.writerrows(self.alldata)
        csvfile.close()
        
if __name__='__main__':
    controller=Controller(10)
    controller.run()
    controller.saveDataCSV()

APP性能測試—流量

獲取進程ID:adb shell ps | grep(findstr) package

根據進程ID獲取流量:adb shell cat/proc/pid/net/dev pid代表進程ID號,其余照抄

結果:

  Receive APP接收的數據

  Transmit APP發出的數據

這2個加上的總值就是這個APP使用的流量,eth0 和eth1代表2個網卡的流量數據

【流量】性能測試腳本

 

#coding:utf8
import time,os,csv,string

#控制類
class Controller(object):
    def __init__(self,count):
        #定義測試的參數
        self.counter=count
        #定義收集數據的數組
        self.alldata=[('timestamp','traffic')]

    #單次測試過程
    def testprocess(self):
        #執行獲取進程ID的命令
        result=os.popen('adb shell ps | grep packagename')
        #獲取進程ID
        pid=result.readlines()[0].split("")[5]
        #獲取進程ID使用的流量
        traffic=os.popen('adb shell cat/proc/'+pid+'/net/dev')
        for line in traffic:
            if "eth0" in line:
                #將所有空行換成#
                line='#'.join(line.split())
                #按#號拆分,獲取收到和發出的流量
                receive=line.split('#')[1]
                transmt=line.split('#')[9]
            elif "eth1" in line:
                #將所有空行換成#
                line='#'.join(line.split())
                #按#號拆分,獲取收到和發出的流量
                receive2=line.split('#')[1]
                transmt2=line.split('#')[9]
                
            #計算所有流量之和
            alltraffic=string.atoi(receive)+string.atoi(transmit)+string.atoi(receive2)+string.atoi(transmit2)
            #按KB計算流量值,因為獲取到的值是bit單位,除以1024就換算成了KB為單位的流量值
            alltraffic=alltraffic/1024
            #獲取當前時間
            currenttime=self.getCurrentTime()
            #將獲取到的數據存儲到數組中
            self.alldata.append((currenttime,alltraffic))
            
    #多次測試過程
    def run(self):
        while self.counter>0:
            self.testprocess()
            self.counter-=1
            #每5秒鍾采集1次數據
            time.sleep(5)
    
    #獲取當前的時間戳
    def getCurrentTime(self):
        currentTime=time.strftime(("%Y-%m-%d %H:%M:%S",time.localtime())
        return currentTime
    
    #數據的存儲
    def saveDataToCSV(self):
        csvfile=file('traffic.csv','wb')
        writer=csv.writer(csvfile)
        writer.writerrows(self.alldata)
        csvfile.close()
    
    
if __name__='__main__':
    controller=Controller(3)
    controller.run()
    controller.saveDataToCSV()

APP性能測試—電量

獲取電量命令:adb shell dumpsys battery

返回值:level值表示電量  

切換非充電狀態 命令:adb shell dumpsys battery set status 1

Status 值為什么設置為1呢?其實只要非2就可以了,因為2是代表充電狀態

【電量】性能測試腳本

#coding:utf8
import csv,os,time

#控制類
class Controller(object):
    def __init__(self,count):
        def __init__(self,count):
        #定義測試的參數
        self.counter=count
        #定義收集數據的數組
        self.alldata=[('timestamp','power')]

    #單次測試過程
    def testprocess(self):
        #執行獲取電量的命令
        result=os.popen('adb shell dumpsys battery')
        #獲取電量的level
        for line in result:
            if "level" in line:
                power=line.split(':')[1]
                
        #獲取當前的時間
        currenttime=self.getCurrentTime()
        #將獲取到的數據存到數組中
        self.alldata.append((currenttime,power))
        
    #多次測試過程
    def run(self):
        #設置手機進入非充電狀態
        os.popen('adb shell dumpsys battery set status 1')
        while self.counter>0:
            self.testprocess()
            self.counter-=1
            #每5秒鍾采集一次數據
            time.sleep(5)
    
    #獲取當前的時間戳
    def getCurrentTime(self):
        currentTime=time.strftime(("%Y-%m-%d %H:%M:%S",time.localtime())
        return currentTime
    
    #數據的存儲
    def saveDataToCSV(self):
        csvfile=file('power.csv','wb')
        writer=csv.writer(csvfile)
        writer.writerrows(self.alldata)
        csvfile.close()
   
if __name__=='__main__':
    controller=Controller(3)
    controller.run()
    controller.saveDataToCSV()

APP性能測試—內存

獲取內存命令:adb shell top

例:adb shell top -d 1   -d表示命令刷新的頻率 1表示1秒種。上列命令表示1秒鍾取一次內存的值

例:adb shell top -d 1 > meminfo   將結果輸入到一個文件meminfo

Cat meminfo 查看數據文件meminfo 里面有剛才取到的所有內存數據

過濾meminfo里的數據,命令:Cat meminfo | grep package

內存的取值:

  VSS Virtaul Set Size   虛擬耗用內存

  RSS Resident Set Size    實際使用物理內存

取完值之后,做成曲線圖 如果內存長期處於穩定狀態,說明我們的APP沒有內存泄露的情況

【內存】性能測試腳本

#coding:utf8
import csv,os,time

#控制類
class Controller(object):
    def __init__:
        def __init__(self,count):
        #定義測試的參數
        self.counter=count
        #定義收集數據的數組
        self.alldata=[('timestamp','meminfo')]

    #分析數據
    def analyzedata(self):
        content=self.readfile()
        i=0
        for line in content:
            if "com.android.browser" in line:
                print line
                line="#".join(line.split())
                vss=line.split("#")[5].strip("K")
                rss=line.split("#")[6].strip("K")
                
                #將獲取到的數據存儲到數組中
                self.alldata.append((i,vss,rss))
                i+=1
    
    #數據的存儲
    def saveDataToCSV(self):
        csvfile=file('meminfo.csv','wb')
        writer=csv.writer(csvfile)
        writer.writerrows(self.alldata)
        csvfile.close()
    
    #讀取數據文件
    def readfile(self):
        mfile=file('meminfo','r')
        content=mfile.readlines()
        mfile.close()
        return content
    
if __name__=="__main__":
    controller=Controller()
    controller.analyzedata()
    controller.saveDataToCSV()

APP性能測試—FPS

FPS:frames per second 每秒的幀數,每秒60幀認為是一個正常的幀數 如果大於60幀可以認為是一個卡幀的現象

FPS查看方式: 開發者選項 → GPU呈現模式分析

FPS查看結果:在屏幕上顯示為條形圖 手機下方會出現一個條形圖。條形圖的上方會有一根綠色的線,表示16毫秒 如果很多在綠線以上就代表FPS有問題,有卡幀的現象

 

APP性能測試—過度渲染

過度渲染:描述的時屏幕上的某個像素在同一幀的時間內被繪制了多次

過度渲染查看方式: 開發者選項 → GPU過度繪制

***END

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM