移动性能测试 android 端取 cpu,fps,men,wifi/gprs 流量等值



最近在做性能监控移动端的方面的研究,把遇到的问题总结下:

  • 尽量不要用split切割的方式取值,因为不同手机取值不一样,还可能会出现数组越界
  • 取cpu占用情况时,不要用top和dump cpuinfo,因为他们拿到的是几个cpu的值,会出现超过100%

取men占用情况

cmd = "adb -s " +  devices +" shell  dumpsys  meminfo %s" % (pkg_name)
    print(cmd)
    output = subprocess.check_output(cmd).split()
    s_men = ".".join([x.decode() for x in output]) # 转换为string
    print(s_men)
    men2 = int(re.findall("TOTAL.(\d+)*", s_men, re.S)[0])
    print(men2 )

取电量占用情况

def get_battery(devices):
    cmd = "adb -s " + devices + " shell dumpsys battery"
    print(cmd)
    output = subprocess.check_output(cmd).split()
               stderr=subprocess.PIPE).stdout.readlines()
    st = ".".join([x.decode() for x in output]) # 转换为string
    print(st)
    battery2 = int(re.findall("level:.(\d+)*", st, re.S)[0])
    writeInfo(battery2, PATH("../info/" + devices + "_battery.pickle"))
    return battery2

取wifi,gprs上下行流量

def get_flow(pid, type, devices):
    # pid = get_pid(pkg_name)
    _flow1 = [[], []]
    if pid is not None:
        cmd = "adb -s " + devices + " shell cat /proc/" + pid + "/net/dev"
        print(cmd)
        _flow = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE).stdout.readlines()
        for item in _flow:
            if type == "wifi" and item.split()[0].decode() == "wlan0:":  # wifi
                # 0 上传流量,1 下载流量
                _flow1[0].append(int(item.split()[1].decode()))
                _flow1[1].append(int(item.split()[9].decode()))
                print("------flow---------")
                print(_flow1)
                break
            if type == "gprs" and item.split()[0].decode() == "rmnet0:":  # gprs
                print("-----flow---------")
                _flow1[0].append(int(item.split()[1].decode()))
                _flow1[1].append(int(item.split()[9].decode()))
                print(_flow1)
                break
    else:
        _flow1[0].append(0)
        _flow1[1].append(0)

得到cpu几核

def get_cpu_kel(devices):
    cmd = "adb -s " + devices + " shell cat /proc/cpuinfo"
    print(cmd)
    output = subprocess.check_output(cmd).split()
    sitem = ".".join([x.decode() for x in output])  # 转换为string
    return len(re.findall("processor", sitem))

取cpu使用情况

'''
 每一个cpu快照均
'''
def totalCpuTime(devices):
    user=nice=system=idle=iowait=irq=softirq= 0
    '''
    user:从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。
    nice:从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
    system 从系统启动开始累计到当前时刻,处于核心态的运行时间
    idle 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间
    iowait 从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41)
    irq 从系统启动开始累计到当前时刻,硬中断时间(since 2.6.0-test4)
    softirq 从系统启动开始累计到当前时刻,软中断时间(since 2.6.0-test4)
    stealstolen  这是时间花在其他的操作系统在虚拟环境中运行时(since 2.6.11)
    guest 这是运行时间guest 用户Linux内核的操作系统的控制下的一个虚拟CPU(since 2.6.24)
    '''
    cmd = "adb -s " + devices +" shell cat /proc/stat"
    print(cmd)
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         stdin=subprocess.PIPE, shell=True)
    (output, err) = p.communicate()
    res = output.split()

    for info in res:
        if info.decode() == "cpu":
            user = res[1].decode()
            nice = res[2].decode()
            system = res[3].decode()
            idle = res[4].decode()
            iowait = res[5].decode()
            irq = res[6].decode()
            softirq = res[7].decode()
            print("user=" + user)
            print("nice=" + nice)
            print("system=" + system)
            print("idle=" + idle)
            print("iowait=" + iowait)
            print("irq=" + irq)
            print("softirq=" + softirq)
            result = int(user) + int(nice) + int(system) + int(idle) + int(iowait) + int(irq) + int(softirq)
            print("totalCpuTime"+str(result))
            return result



'''
每一个进程快照
'''
def processCpuTime(pid, devices):
    '''

    pid     进程号
    utime   该任务在用户态运行的时间,单位为jiffies
    stime   该任务在核心态运行的时间,单位为jiffies
    cutime  所有已死线程在用户态运行的时间,单位为jiffies
    cstime  所有已死在核心态运行的时间,单位为jiffies
    '''
    utime=stime=cutime=cstime = 0
    cmd = "adb -s "+ devices + " shell cat /proc/" + pid +"/stat"
    print(cmd)
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         stdin=subprocess.PIPE, shell=True)
    (output, err) = p.communicate()
    res = output.split()
    utime = res[13].decode()
    stime = res[14].decode()
    cutime = res[15].decode()
    cstime = res[16].decode()
    print("utime="+utime)
    print("stime="+stime)
    print("cutime="+cutime)
    print("cstime="+cstime)
    result = int(utime) + int(stime) + int(cutime) + int(cstime)
    print("processCpuTime="+str(result))
    return result

'''
计算某进程的cpu使用率
100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,如果是多核情况下还需乘以cpu的个数);
cpukel cpu几核
pid 进程id
'''
def cpu_rate(pid, cpukel, devices):
    # pid = get_pid(pkg_name)
    processCpuTime1 = processCpuTime(pid, devices)
    time.sleep(1)
    processCpuTime2 = processCpuTime(pid, devices)
    processCpuTime3 = processCpuTime2 - processCpuTime1

    totalCpuTime1 = totalCpuTime(devices)
    time.sleep(1)
    totalCpuTime2 = totalCpuTime(devices)
    totalCpuTime3 = (totalCpuTime2 - totalCpuTime1)*cpukel

    cpu = 100 * (processCpuTime3) / (totalCpuTime3)
    print(cpu)

得到fps

'''
@author fenfenzhong
'''


def get_fps(pkg_name, devices):
    _adb = "adb -s " + devices +" shell dumpsys gfxinfo %s" % pkg_name
    print(_adb)
    results = os.popen(_adb).read().strip()
    frames = [x for x in results.split('\n') if validator(x)]
    frame_count = len(frames)
    jank_count = 0
    vsync_overtime = 0
    render_time = 0
    for frame in frames:
        time_block = re.split(r'\s+', frame.strip())
        if len(time_block) == 3:
            try:
                render_time = float(time_block[0]) + float(time_block[1]) + float(time_block[2])
            except Exception as e:
                render_time = 0

        '''
        当渲染时间大于16.67,按照垂直同步机制,该帧就已经渲染超时
        那么,如果它正好是16.67的整数倍,比如66.68,则它花费了4个垂直同步脉冲,减去本身需要一个,则超时3个
        如果它不是16.67的整数倍,比如67,那么它花费的垂直同步脉冲应向上取整,即5个,减去本身需要一个,即超时4个,可直接算向下取整

        最后的计算方法思路:
        执行一次命令,总共收集到了m帧(理想情况下m=128),但是这m帧里面有些帧渲染超过了16.67毫秒,算一次jank,一旦jank,
        需要用掉额外的垂直同步脉冲。其他的就算没有超过16.67,也按一个脉冲时间来算(理想情况下,一个脉冲就可以渲染完一帧)

        所以FPS的算法可以变为:
        m / (m + 额外的垂直同步脉冲) * 60
        '''
        if render_time > 16.67:
            jank_count += 1
            if render_time % 16.67 == 0:
                vsync_overtime += int(render_time / 16.67) - 1
            else:
                vsync_overtime += int(render_time / 16.67)

    _fps = int(frame_count * 60 / (frame_count + vsync_overtime))

    # return (frame_count, jank_count, fps)
    print("-----fps------")
    print(_fps)

取值cpu参考资料

不多说废话,看题目,本教程适合练手,会python+android基础的人群,文件较大,上传乃是下载链接,下面上目录: 1-1 课程导学 2-1 如何学好Android App性能测试? 2-10 详解【电量】监控值的获取方法 \' D, l" p) d6 d. K9 [7 p 2-11 详解【电量】监控脚本实现和数据分析 O, e4 X& K0 S% h8 v8 V9 ? 2-12 详解【内存】监控值的获取方法 k! e6 e# C" K% z9 k- l 2-13 详解【内存】监控脚本实现和数据分析0 d; e- S% G6 r3 H: g 2-14 详解【FPS&过度渲染】的概念和监控方法 - 分析页面卡慢的方法# G! _2 O9 T* j" K s3 v6 C0 l 2-2 工欲善其事必先利其器-性能测试环境准备 2-3 详解【启动时间】监控值的获取方法0 n( p* l; g C 2-4 详解【启动时间】监控脚本实现% B2 z( C( E& S: n r1 e 2-5 详解【启动时间】数据分析 2-6 【启动时间】时间戳差值监控方法概要介绍 2-7 详解【CPU】监控值的获取方法、脚本实现和数据分析 2-8 详解【流量】监控值的获取方法7 r7 ~/ D5 |+ h9 m9 i6 p) b: Y 2-9 详解【流量】监控脚本实现和数据分析2 [9 {# {$ c9 k/ T, `/ t" \ 3-1 为什么需要使用框架实现自动化测试? 3-10 UnitTest框架之TestCase,TestSuite,TestRunner简介3 A2 {1 F2 @; K 3-11 UnitTest框架之TestSuite,TestRunner自动化测试 3-12 数据驱动框架DDT简介 3-13 数据驱动框架DDT的使用方法 3-14 数据驱动框架DDT实战; 3-2 准备一个被测APP 3-3 工欲善其事必先利其器-自动化测试环境准备 3-4 Android App自动化测试(一) 3-5 Android App自动化测试(二) 3-6 Android App自动化测试(三) 3-7 UnitTest框架之TestFixture简介 3-8 UnitTest框架之TestFixture自动化测试(一) 3-9 UnitTest框架之TestFixture自动化测试(二) 4-1 如何学好Android App API接口测试? 4-10 Fiddler构造HTTP Get请求 4-11 Fiddler构造HTTP Post请求 4-12 Fiddler抓取手机上的网络数据包 4-13 为什么使用PostMan做API接口测试 4-14 工欲善其事必先利其器-PostMan工具准备 4-15 PostMan测试HTTP Get请求 4-16 PostMan测试HTTP Post请求 4-17 数据驱动DDT实现API接口自动化测试简介) 4-18 Python requests测试HTTP中的Get、Post请求 4-19 数据驱动DDT实现API接口自动化测试(一) 4-2 什么是API 4-20 数据驱动DDT实现API接口自动化测试(二); 4-3 抓包神器Fiddler简介 4-4 Fiddler抓包原理解析 4-5 Fiddler修改客户端发出的请求(一) 4-6 Fiddler修改客户端发出的请求(二) 4-7 Fiddler修改服务器端返回的内容 4-8 Fiddler实现会话的过滤、对比及请求的编解码 4-9 Fiddler实现Host的配置 5-1 测试工程师为什么需要掌握持续集成? 5-2 持续集成的概念、流程和意义 5-3 讲解持续集成工具Jenkins3 5-4 Jenkins工具密码的修改 5-5 Jenkins工具的配置说明 5-6 Jenkins工具系统配置和Job配置 5-7 Jenkins工具手动持续集成实战 5-8 Jenkins工具自动化持续集成实战 6-1 Native App自动化测试及Appuim框架介绍 6-2 自动化测试环境、元素识别工具、脚本设计原则-LOVE原则的讲解 6-3 Native App自动化脚本的实现 6-4 Appium自动化测试框架API讲解与案例实践(一) 6-5 Appium自动化测试框架API讲解与案例实践(二) 6-6 Appium自动化测试框架API讲解与案例实践(三) 6-7 Appium自动化测试框架API讲解与案例实践(四) 6-8 Appium自动化测试框架API讲解与案例实践(五) 6-9 Appium自动化测试框架API讲解与案例实践(六) 7-1 Hybrid App自动化测试概要 7-2 Appium基于Sele
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值