iOS电量相关问题一直是测试人员头疼的事情,电量测试怎么开展、问题怎么复现和跟进定位、用户反馈电量相关的问题我们如果获取更多的信息等等,一直都没有一个好的解决方案,以至于我们面对电量相关的问题时,总是束手无策。整个项目组经常收到这样的一种反馈:你看,你们开发的APP,我还没怎么用呢,耗电量就排第一了。对于这样的反馈,我们能做些什么呢?之前我们是迷茫的,但经过一段时间的尝试和努力之后,事情有了一些改观。
在之前很长一段时间,我们都是用这种可怜的方式进行电量测试的:
1、选定测试场景以及时长;
2、给手机充放电,让手机剩余电量在我们预设的值,比如90%,每个场景测试开始时,保证手机都是这一电量;
3、手机系统设置,一般要关注屏幕亮度、蓝牙、定位、通知消息、音量、后台应用等等,为保证简单,通常是全部关闭或调到最小即可;
4、记录开始时的剩余电量,并执行测试,在测试结束后再记录一次剩余电量,两个电量差,就为该场景在一定时长内的耗电量;剩余电量嘛,直接读手机上展示的值或是通过接口获取(后面会介绍)均可以,几乎没有区别;
真是够简陋,但并非完全没有用,明显的电量消耗问题,还是可以发现,只要选得场景对了就可以。要是发现不了问题也不会一直用这个方法了不是。嘿嘿。
后面我们还将这种方案做了优化,流程不变,但是全自动化,人工只参与数据出来后的整理即可。具体的方法是,在手机和mac之前,加了一块Arduino开发板,通过mac端的指令,可以智得控制开发板通电或是断电,以达到手机充电或是放电的效果。
但不管怎么全自动化都好,终归还是最粗放的方式,没有具体的数据,没法帮助定位,如果还是个偶现的问题,那就更加束手无策,只能作罢。
慢慢得,我们开始去做一些新的尝试,能不能获取到更多更详细的电量数据,是我们的主要目标。
我们想得也比较简单,执着得认为,肯定是有一些我们没有发现的接口,可以获取到一些详细的数据,要不然系统是怎么计算每个APP的耗电量的呢?其实在某一段时间之内,确实如我们所想,但并非一直如此。
最初我们用到的是UIDevice类batteryLevel接口。这个接口只能获取到剩余电量百分比,目前世面上能见到的所有iOS系统版本都可用,如上文所提到的,他和系统界面上展示的值几乎没有区别,唯一不同的是,他是以mAh为单位计的,以这个值计算的剩余电量百分比,就是系统上显示的那个值。这样看来,这个接口也没有什么多大的意义。还得继续尝试。
接着我们使用到的是IOKit中的IOPMPowerSource接口,私有接口,调用方式如下:
在iOS 10及以上的系统上,能获取到的信息如下:
看看关键信息:
第三行CurrentCapacity是当前的剩余电量;
第六行FullyCharged是否满电量;
第八行IsCharging是否正在充电;
第九行MaxCapacity最大电池容量;
第十行Voltage当前电压。
信息是多了一些,有当前电压值,有剩余电量。这个有什么用呢?我们先科普一点点小知识。
首先,某一设备的电压,基本是在一定范围之内变动的,相对稳定的一个值。就像iPhone 6P的电压,基本是在4V上下。当电池剩余电量越少时,电压值会变得越小,但波动不大。电压过小时,可能会引起手机直接关机,这也是为什么有时还有20%电量,但手机却开不了机了。新的电池,电压波动会小一些,越是老化,电压波动可能越大。所以电压这个值能用来判断当前电池的健康度。
然后是剩余电量2548,他的单位是mAh。手机电池常用类似1000mAh这样的标识,这不是具体的电量,光看这个值,能解理到的含义是,以1000mA的电流来放电,能放1小时。或者说,以200mA的稳定电流放电,能放5小时。但明显这样意义并不大。因为我们还不知道电池在工作时,会以多少mA的电流工作,所以也就不知道能用多久,我们想知道的是,电池到底还有多少电,这个才是一个具体的值。上面提过,电压是相对固定的,我们可以算出具体剩余多少电,以1000mAh,粗略计电压稳定为4V,根据公式计算得出W=U*I*t=4v*1000mAh=4000mWh。这个就是当前电池剩余的电量。当计算剩余电量的百分比的时候,用哪个值去算都一样了。
以上是IOPMPowerSource接口在iOS10及以上系统上获取的信息。但事实上,在iOS 9及以前的系统上,能获取到更多更详细的信息,大部分是一些硬件的固定信息,对我们测试没有帮助。但也有一些其他有用的信息,比如说当前的温度,电流,都是很有用的信息,如下图:
温度能用来直接判断当前的发热情况,电流能直接判断当前的电池发电功率,都可以有效判断当前电池的使用状态。
但是这个接口拿到的数据,仍然是不够具体,全是整机的电池情况,没有具体到某一个应用或是其他维度的电量统计。所以,还得继续摸索。
这一次我们应用到的是BatteryUsageUI.bundle中PLBatteryUsageUIQuery,也是个私有接口。这里卖个关子,实现就不帖了,有心的同学可以根据我的关键字找到具体的东西。这个接口就厉害了,具体得说,他能拿到每一个APP的CPU\GPU\显示\网络\存储等前后台所有详细信息,一个巨大的表。
当我们探索到这一步时,激动不已,以为光明就在眼前了。可是事实却是,这个接口早在iOS9的第一个版本,就完全被封了,只能在iOS 8上的机子上拿到数据。而且经过多次确认后,我们发现,这个数据是每个小时才会更新一次,并不是实时的。
但尽管如此,还是大大得增强了我们继续探索的信心,我们第一次获取到了每一个App的电量消耗情况,而且我们很确信,苹果iOS的电量排行榜,就是根据这些数据计算出来的。因为,我们在这之前,已经发现在越狱环境下有个工具,叫DetailedBatteryUsage,这个插件只做了一件事情,就是把系统设置里,电池的显示方式设置成了“2”,而默认的显示方式是“0”。设置为“2”以后,就可以在电池设置里看到很详细的信息,如下图:
跟我们用接口拿到的数据是一致的,所以我们确认电量排行榜数据来至于这个接口,而且,系统一直在调用这个接口在统计电量相关的信息,只是对用户而言不可见,而且接口也不可见。在越狱环境下能拿到这些数据,对我们定位问题已经有很大的帮助了,但是一方面这些数据是系统显示出来的,我们处理很不方便,效率也低,另一方面,这些数据只能在越狱的机器上拿到,而目前主流的系统都还是不能越狱的。我们不得不再进一步。
经过长时间的探索,我们的目标越来越清晰,但是路却越来越窄,因为能用的接口都被官方给屏蔽了,很长一段时间内,我们都没有任何进展。直到无意中发现了官方的工具sysdiagnose。这是苹果日志系统的统称,苹果经常会询问是否要官方帮忙诊断和定位问题时,上传的就是sysdiagnose的各种日志。
Sysdiagnose很庞大,每天上几百M的日志,记录电池、第三方APP、各种系统功能和应用的所有运行情况。
Sysdiagnose怎么使用呢?简单得说,就是需要一个开发者账号,然后到苹果开发者网下载对应的证书。不需要越狱,没有系统限制,这个特别关键。关于怎么使用,有明确的说明:
9
当然每一类不同的日志,都对应不同的证书,以上说明是针对电池电量的。
电量日志是sysdiagnose系统中最庞大的一块。电量日志每天有几十到一百M,他是一个庞大的数据库,里面有267张表,记录了电池电量的各维度信息。看来要弄懂电量的数据来源,必须要弄明白这些表之前的联系以及各自的意思。
经过几周的折腾,我们弄明白了几个关键的顶部的表格,下面列出来分享给大家:
通过这些表格数据,我们能明白,系统记录了哪一些数据,他们之前的关系,哪些是对我们有用的。数据非常全面,我只能说苹果威武。
有了这样全面的官方数据,我们的测试怎么做呢?
1、首先,上线前的电量测试,只要装上对应的证书,便可开始执行测试,只要记下哪个时间段对应的是哪个场景,然后测试完后,取下系统的数据库,便可以对当次的电量做较全面的评价,例如,某个APP在某场景下,20分钟运行时间,显示耗电100mWh,CPU耗电20mWh,运行温度是32度,平均电流是110mA,是不是很酷?这样的数据,一旦异常,对于问题的定位帮助也比较大,点个赞。
2、用户反馈的问题,不再没有头绪,只需要装证书发送给他,让他装上,半小时后便可以获取到最近几天的所有电量信息,用于跟进和定位问题。酷不酷?想不想学?
不仅如此,这些关键数据,还让我们弄清了两个关键问题,一个是剩余电量是怎么计算的,另一个是电量排行榜是怎么计算的,我一一列举。
iOS系统每20秒会读取一次系统电量相关数据记录入整机电量数据库,主要内容有当前电流,电压,剩余电量,最大电量,温度,是否在充电,充放电次数。
1、电流以mA计,直接通过硬件测得,是计算其他数据的基础,iPhone工作时,电流一般在1mA到700mA之间。超过500mA电池很容易发热。
2、电压以mV计,通过硬件测得,是计算其他数据的基础,iPhone工作时,电压几乎一直恒定在4V左右。测试过程中出现过的最高电压是4.3V。
3、剩余电量是以mAh计,他和最大电量是相对值,我们看到的电量百分比是这两个值的比值。电量最大值是一个理论值,1000mAh的意义是,以1000mA的恒定电流放电时,能放1小时。他最大值并不固定,他会随着电压而发生一些波动。
4、温度也通过硬件接口获得,可以作为一个参考值,测试过程中出现的最高温度是37度,能明显感觉到发热了。
5、是否在充电,如果是在充电过程中,使用的任何应用,具体电量都不作统计,不入数据库,而只统计整机的电量。
6、充放电次数,以充放一次最大电池容量记为一次,充放电次数可以作为电池老化程度的一个根据。
下面再来说说到底是怎么计算的。
假如充满电是1000mAh,系统会每20秒读一次电流值,以及判断是在充电还是放电,记算这段时间的功耗,逐步累加。如半小时后还有800mAh,剩余电量就是80%。
1、首先要说明的是,电量排行榜显示的不是实时的数据,他有1小时内的延迟。同时他与系统显示的剩余电量百分比也不是同一套计算体系。
2、iPhone用来记录电量相关数据的数据库极为庞大,有在概265张表,每天超10M的数据。
3、每一个安装到iPhone的应用,在系统级都会有一个ID标注,称作结点ID。
4、系统电量的消耗分为主要以下大类,每一种都作为电量消耗的根结点。isp\apsocbase \display\wifi data\GPU venc\venc\CPU\restofsoc\GPS\DRAM。
5、系统中每个应用都有几种状态,分别是不运行、前台活跃、前台不活跃(一般应用间切换时出现)、后台、暂停(在后台但没有运行,程序还在内存中)。
6、系统每小时记录了每一个根结点被哪些应用占用,应用的状态是怎么样的,每应用消耗了多少能量,总共消耗了多少,比如某一小时内,某个APPCPU\GPU\GPS\DRAM\显示各耗电20mAh,共100mAh,这小时内所有APP耗电200mAh,那么该APP耗电占比50%。
总结一下,电量测试从农业时代,到工业时代,再进大数据时代,是量变到质量的过程。我们做了长时间的探索,最终还是站在巨人的肩膀上,实现了最初预想的目标,走了很多弯路,由于研究的人很少,经常一些关键词,google出来的信息就两三条,很容易走进死胡同里,但也正因为这样,也没有在一条错的路上一直走,总算是有点收获,很是感慨。
关注微信公众号:腾讯移动品质中心TMQ,获取更多测试干货!