APP耗电量测试
现象
APP耗电,导致电池续航能力不佳,如下图,在小米MIX2和iPhone X机型上后台静默一小时各应用的耗电排行:


基本概念
相对于PC来说,移动设备的电池电量是非常有限的,保持持久的续航能力尤为重要。另外,Android的很多特性都比较耗电(如屏幕、GPS、sensor传感器、唤醒机制、CPU、连网等的使用),我们必须要慎重检查APP的电量使用,以免导致用户手机耗电发热,带来不良体验。
场景设计
主要的耗电场景有:
cpu:复杂的运算逻辑、死循环等会直接导致CPU负载过高,会导致耗电;
wakelock:只要有应用拿到wakelock这个锁,系统就无法进入睡眠状态。频繁wakelock或者申请了wakelock没有释放,会导致耗电;
wifiscan和wifilock:wifiscan和wifilock也会导致手机的wifi模块处于激活状态,频繁的wifiscan或者wifilock不释放,会导致耗电;
sensor:传感器打开后会导致系统持续监听设备外围环境的数据变化,使用后不及时关闭,会导致耗电;
network:大量的数据传输,或者长时间的移动网络数据传输导致radio长期处于活跃状态,会导致耗电;
gps:gps也是一种传感器,定位中没有及时关闭,会导致耗电;
业务层面,用户最核心基础的模块:
新增的基础逻辑,倘若入口明显,潜在较大访问,必须保证性能;
活动需要,因为活动上新的逻辑,存在较大的用户访问,需尽力提升用户体验;
反馈体验不好的模块;
监控分析
耗电原理
1、各部件单位时耗电:各部件单位时耗电信息保存在power_profile.xml文件中,如下图(以魅族MX6为例):

2、运行时长
电量(mAh)=各部件单位时耗电量(mA)*各部件运行时长(h)
数据获取

测试环境
1、恢复出厂设置,排除其他APP对耗电的影响,减少干扰因素;
2、测试过程中,不出现充电情况;
3、Android 5.0 以上的设备;
4、通过wifi连接电脑和手机;
adb tcpip 5555
adb connect 192.168.1.101 (Android设备IP地址)
测试步骤
1、首先,电脑用数据线连接手机设备,开启设备的开发者模式后,使用adb devices命令,能够看到设备在线
2、打开电池数据获取:
adb shell dumpsys batterystats --enable full-wake-history
3、重置电池数据:
adb shell dumpsys batterystats --reset
4、接下来可以拔掉数据线,在手机上对被测试app执行相应的用例进入测试场景
5、操作完成后,电脑再次连接设备,执行命令:
adb shell dumpsys batterystats > xxx.txt
# 因为bugreport时间比较长,我们放到后面执行来减少与前面dumpsys的数据的偏差
Android 7.0及以上:
adb bugreport bugreport.zip
Android 6.0及以下:
adb bugreport > bugreport.txt
获取指定app的信息:
adb shell dumpsys batterystats > com.example.android.sunshine.app > batterystats.txt
6、打开Battery Historian平台将bugreport.txt导入, 并点击submit进行分析
案例分析
Case1:应用后台静默,wakelock长时间未释放

如上图,在一次版本的耗电量测试中发现耗电量显著增加,通过进一步定位发现是应用中引入的某个SDK为了在后台维持心跳使用了wakelock,而在用户将应用切入后台后一直持有没有释放,随后经过跟对应的开发同学沟通进行了优化更改了实现方式去掉了wakelock,耗电量恢复正常。
Case2:应用后台静默,各种sensor持续工作
在做另外一个版本的专项测试中发现耗电量数据异常,如下图,通过测试结果分析发现是应用在后台驻留了51分钟,各种传感器也同样工作了51分钟导致耗电量显著增加,后经过排查确定是引入的推送SDK导致的,经过修改调用方式解决。

Case3:应用前台静默,各种sensor持续工作
通过前台静默(无任何操作)15分钟,发现耗电量比上个版本高了一倍,如下图: 应用前台静默期间加速度、重力、陀螺仪这三个传感器一直被使用。

跟开发沟通后确定是由于另外一个部门提供的SDK导致的,该SDK采集传感器数据的策略有问题导致会在应用启动后一直采集造成耗电,解决方案是按照时间窗口来采集数据, 比如每次打开APP采集5分钟传感器数据, 然后关闭传感器数据采集。
通过标准

最佳实践


附:iOS耗电量测试
上面主要是讲的关于Android的耗电量测试方法及分析,当然思路是一样的,关于iOS的耗电量测试由于还没有具体的数据,这里给出一些我调研尝试过的一些方法:
1、系统接口
iOS 10系统内置的Setting里可以查看各个APP的电池消耗,系统接口能获取到整体的电池利用率,以及充电状态。
该方案不能检测固定某一时间段内的电池精准消耗。
2、硬件检测
通过硬件PowerMonitor可以精准地获得应用的电量消耗。
步骤如下:
a. 拆开iOS设备的外壳,找到电池后面的电源针脚
b. 连接电源监控器的设备针脚
c. 运行应用
d. 测量电量消耗
该方案成本太高并不适合我们的测试工作。
3、软件工具检测
由于iOS系统的封闭性,获取功耗数据只能通过Xcode自带的Instruments工具实现,步骤如下:
1. 断开iOS设备与Mac的连接(充电时测试功耗会导致数值不准确)
2. iOS设置选项->开发者选项->Logging->Start Recording
3. 进入需要测试电量的场景操作
4. 操作完成后进入开发者选项点击Stop Recording
5. 将iOS设备和Mac连接
6. 打开Instruments,选择Energy Log
7. 选择File->Import Logged Data from Device
8. 保存的数据以时间轴输出到Instrument面板
该方案作为性能测试的补充方案具有较高的权威性,但输出的数据不直观,用于功耗测试的效果并不理想。
4、使用Battery Life进行功耗测试
该APP无需额外费用,输出结果直观(可得到毫安数及百分比)准确,可以尝试使用。
APP耗电量测试的更多相关文章
- Android手机app耗电量测试工具 - Gsam Battery Monitor
这段时间需要测试一个Android手机app的耗电量,在网上找了一个工具,Gsam Battery Monitor,觉得挺好用,和大家分享一下. 安装app后打开,可以看到主界面是这样的 点击一下上图 ...
- app耗电量测试工具--PowerTutor
PowerTutor是一款用来测试手机功耗的小工具,它可以只管地展示手机系统主要的组件和各种用户app产生的功耗数据.它可以统计app的屏幕功耗(LCD).CPU功耗以及WiFi和3G网络功耗,我们可 ...
- Battery Historian之App耗电量测试
一.Battery Historian测试所需环境:Go+Git+Python+Java+Battery Historian源码 下载Battery Historian源码并且运行的步骤如下: 1.打 ...
- 智能手机的耗电特征及APP耗电量测试的两种方法
文章陈述了手机发展趋势及耗电特性,集中讨论了时下最为关心的智能手机耗电问题,并介绍了测量手机软件耗电量的两种方法.此外还解释了为何运营商此前会提出收取微信的费用,心跳机制是什么. 美国著名手机公司Pa ...
- iOS测试-如何指标量化app耗电量和性能XCTest Metrics
对于app端的专项测试,Android端我们可以用adb或者一些三方工具进行(例如itest)进行实时的性能监控,iOS端的话也可以用用一些三方的工具,但是需要嵌入到我们的项目当中,今天来介绍下Xco ...
- iOS耗电量测试
iOS耗电量测试 本文主要介绍的是使用Energy Diagnostics Instruments来进行iOS耗电量测试. 一.使用方法: 1)iOS 设置选项 ->开发者选项 ->log ...
- Android CPU耗电量测试
Android CPU耗电量测试 在测试Android app时,不仅仅要关注app的功能,也好关注app的性能指标,cpu.内存.流量.电量等.简单介绍下电量测试中的cpu耗电. 影响耗电的因素 C ...
- 移动app传统测试流程优化
[本文出自天外归云的博客园] 概述 在传统的软件测试流程中,每一期需求从开发到上线都要经历从需求分析与评审.测试用例评审.开发.测试.发布的流程.其中测试包含了后台测试.前端web测试.客户端测试.后 ...
- 如何做好App的测试工作
记得刚开始接触app测试时,可谓是一脸懵状,拿到一个功能不知道该测些什么,会因为测试范围确认不足.测试点考虑不全等导致线上问题,吃一堑才会长一智,栽过几次坑后就学会了如何避免.现总结App测试点如下, ...
随机推荐
- docker限制容器内存使用上限
记录一个项目开发部署中遇到的一个问题,处理经验总结. 问题: 我们的项目使用的是Angular6 + Spring boot + redis + mycat结构,项目部署在容器里面,项目正式部署以后, ...
- H5和PC实现点击复制当前文字的功能,兼容ios,安卓
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 向后台提交数据:cookie,secure_cookie,
向后台提交数据除了前端url,form表单,Ajax外还可以用cookie,secure_cookie,提交更多信息可以在用cookie基础上用session, cookie,secure_cooki ...
- Javascript 对象 - 字符串对象
字符串对象 字符串对象是JavaScript中比较常见的一种基本数据类型,他封装了一个字符串,并且提供了相应的方法.例如连接字符串.取字符串.分割字符串等.JavaScript中字符串是不可变的,原始 ...
- Android string.xml 添加特殊字符
解决项目中在string.xml 中显示特殊符号的问题,如@号冒号等.只能考虑使用ASCII码进行显示: @号 @ :号 : 空格 以下为常见的ASCII十进制交换编码: --> <- ...
- Flutter 布局(一)- Container详解
本文主要介绍Flutter中非常常见的Container,列举了一些实际例子介绍如何使用. 1. 简介 A convenience widget that combines common painti ...
- git 入门教程之版本控制
版本控制 我们知道 git 是分布式版本控制系统,所以称被控制对象是版本本身没错,但是从git 命令中发现,并没有版本这个名词,有的只是commit,所以前几节我一直称其为提交. 为了避免后续教程引发 ...
- Scala依赖注入
控制反转(Inversion of Control,简称IoC),是面向对象编程中的一种设计原则,可以用来降低计算机代码之间的耦合程度.其中最常见的方式叫做依赖注入(Dependency Inject ...
- PostgreSQL分页
转自 https://blog.csdn.net/tomcat_2014/article/details/49947711 如果用过mysql,那么对 select * from xxx limit ...
- Python操作字典(dict)
一.字典定义 >>> dict={} 二.字典元素添加 >>> dict['性别']='男' >>> dict {'性别': '男'} >& ...