IOS app电量测试方法调研

2019-07-14 00:05发布

方法一——硬件检测

通过硬件 PowerMonitor 可以精准地获得应用的电量消耗。步骤如下:
  1. 拆开iOS设备的外壳,找到电池后面的电源针脚。
  2. 连接电源监控器的设备针脚
  3. 运行应用
  4. 测量电量消耗
下图展示了与iPhone的电池针脚连接的电源监控器工具。enter image description here可以参考:Using Monsoon Power Monitor with iPhone 5s
  • 可以精准地获得应用的电量消耗。
  • 设备价格 $771.00 USD
  • 需要拆解手机
链接:https://www.jianshu.com/p/851b0acde9c3

方法二——instruments

步骤

1.iOS 设置选项 ->开发者选项->logging ->start recordingenter image description here2.进行需要测试电量的场景操作后进入开发者选项点击stop recording3.将iOS设备和Mac连接4.打开Instrument,选择Energy Diagnostics5.选择 File > Import Logged Data from Deviceenter image description here6.保存的数据以时间轴输出到Instrument面板

缺点

    1)进行电量测量时,必须断开iOS device和PC的连接,因此不能通过ui自动化测试的方式执行app操作;  2)电量采样速率为1s/次,电量使用level为0-20,1/20:表示运行该app,电池生命会有20个小时;20/20:表示运行该app,电池电量仅有1小时的生命测试精确度为5%;  3)电量测试数据只能通过Energy Diagnostics Instruments查看,不能导出为cvs文件,无法计算整体耗电量、平均耗电量,只能手动计算平均值 

方法三——api接口调用的方式

最初我们用到的是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的CPUGPU显示网络存储等前后台所有详细信息,一个巨大的表。   当我们探索到这一步时,激动不已,以为光明就在眼前了。可是事实却是,这个接口早在iOS9的第一个版本,就完全被封了,只能在iOS 8上的机子上拿到数据。而且经过多次确认后,我们发现,这个数据是每个小时才会更新一次,并不是实时的。但尽管如此,还是大大得增强了我们继续探索的信心,我们第一次获取到了每一个App的电量消耗情况,而且我们很确信,苹果iOS的电量排行榜,就是根据这些数据计算出来的。因为,我们在这之前,已经发现在越狱环境下有个工具,叫DetailedBatteryUsage,这个插件只做了一件事情,就是把系统设置里,电池的显示方式设置成了“2”,而默认的显示方式是“0”。设置为“2”以后,就可以在电池设置里看到很详细的信息,如下图: 
 
   跟我们用接口拿到的数据是一致的,所以我们确认电量排行榜数据来至于这个接口,而且,系统一直在调用这个接口在统计电量相关的信息,只是对用户而言不可见,而且接口也不可见。在越狱环境下能拿到这些数据,对我们定位问题已经有很大的帮助了,但是一方面这些数据是系统显示出来的,我们处理很不方便,效率也低,另一方面,这些数据只能在越狱的机器上拿到,而目前主流的系统都还是不能越狱的。我们不得不再进一步。 

方法四——iOS Diagnostics

  • 什么是iOS Diagnostics

iOS diagnostics 是iOS系统本身自带的一套诊断系统,在这个诊断系统中也记录了电量相关信息,这些信息以Sqlite的形式保存在本地,并定期传给苹果服务器,以供苹果相关人员分析。由此可以通过读取iOS系统记录的数据来进行电量测试,这个数据由iOS系统提供,并且记录了每个App的耗电量,故可以得到比较准确的耗电量信息。 苹果官网提供的电量诊断如图: 
  • 如何获取diagnostics的电量数据库

 

1. iOS10以上设备

通过查阅苹果官方的BugReport网站,发现有一项是:Battery Life。通过查阅官方文档发现,这个方式可以自己获取iOS 诊断的电量数据库详细信息,并通过itunes同步到本地,由此可以拿到相关的电量数据。苹果的官方说明:步骤如下:A. 使用开发者账号下载Profilehttps://developer.apple.com/services-account/download?path=/iOS/iOS_Logs/BatteryLife.mobileconfig,通过airDrop或者email安装到手机上。 B. 静置约半个小时,通过iTunes同步到电脑上C. 从电脑获取电量数据库文件对应目录如下:macos:~/Library/Logs/CrashReporter/MobileDevice/[Your_Device_Name]/Windows:C:Users[Your_User_Name]AppDataRoamingApple ComputerLogsCrashReporterMobileDevice [Your_Device_Name]D. 电量数据库以”Powerlog_”开头,以“.PLSQL” or “.PLSQL.gz”结尾 

2. iOS9及以下设备

提供一个思路:可以通过 mitmproxy(抓包工具) + diags://123456拦截接口的形式获得,接口:https://iosdiags.apple.com/ios/TestConfiguration/1.2  如下图: 
  • 电量数据库的解读与分析

     
拿到电量数据库之后,我们要做的就是通过数据库中存的电量信息来帮助我们分析实际App的耗电量。可以下载SqlLiteStudio.dmg来打开.plsql数据库文件。下载地址:http://sqlitestudio.pl/index.rvt?act=download下面是和电量相关的几个表:PLAccountingOperator_EventNone_Nodes记录了所有应用的noteIDPLAccountingOperator_Aggregate_RootNodeEnergy记录了每个noteID的电量消耗PLAppTimeService_Aggregate_AppRunTime记录了App的运行状态,一小时记录一次PLBatteryAgent_EventBackward_Battery记录了整机的电量变化,20秒记录一次(电压、电流、温度等等)PLBatteryAgent_EventBackward_BatteryUI记录了整机剩余电量百分比,20秒记录一次。(手机屏幕上显示的剩余电量正是基于这个数据)PLIOReportAgent_EventBackward_EnergyModel记录了IO相关的电量消耗(SoC、DRAM、IPS等等)PLSpringBoardAgent_Aggregate_SBNotifications_Aggregat记录了推送通知的时间和数量PLLocationAgent_EventForward_ClientStatus定位的相关信息 一方面我们可以获取整机的电量数据变化情况附:sql如下(SELECT datetime(timestamp, 'unixepoch', 'localtime') AS time, Level AS 电量百分比 FROM PLBatteryAgent_EventBackward_BatteryUI;)通过电量百分比数据可以获得整机在测试期间的电量变化趋势图。 同时,我们也可以精确获取到App在某个测试时间段的电量消耗。通过记录下操作场景的时间段,再读取数据库的数据,就可以精确获取该场景在该机器上的电量消耗情况。通过PLAppTimeService_Aggregate_AppRunTime 表获取到App的运行情况:根据App的运行情况从PLAccountingOperator_Aggregate_RootNodeEnergy这个表获取到App电量消耗情况: 这里就能很清楚的知道所测试的App在某个时间段详细的耗电信息,如2018-03-05上午10点测试某个app时的耗电:
  • 屏幕耗电:47284----56.97%
  • RestOfSOC耗电:9699----11.68%
  • CPU耗电:17472----21.05%
  • WIFI耗电:1995----2.4%
  • DRAM(内存)耗电:2649----3.19%
  • GPU耗电:3907----4.7%
 RootNodeID和设备名的对应关系是定义在数据表PLAccountingOperator_EventNone_Nodes里面的。通过如下sql可以关联查询出不同设备的具体耗电量。附:sql如下(SELECT datetime(a.timestamp, 'unixepoch', 'localtime') AS time, a.Energy, b.Name AS Device FROM PLAccountingOperator_Aggregate_RootNodeEnergy a,PLAccountingOperator_EventNone_Nodes b WHERE a.RootNodeID = b.ID AND NodeID = (SELECT ID FROM PLAccountingOperator_EventNone_Nodes WHERE name = "**.**.**"); 结合表PLBatteryAgent_EventBackward_Battery可以获得此段时间该设备详细的耗电情况:
附:sql如下(SELECT datetime(timestamp, 'unixepoch', 'localtime') AS time,Level AS 电量百分比,Voltage AS 电压,FullAvailableCapacity AS 最大容量,CurrentCapacity AS 当前容量,CycleCount AS 电池循环次数,Temperature AS 电池温度,*FROM PLBatteryAgent_EventBackward_Battery;) 由公式计算出该段时间的耗电量约:W=U*I*t (注意,公式中 I*t即为sql中查询出来的电容量)结合前面的耗电百分比得出该段时间App耗电:
  • 屏幕耗电:56.97%*W=493mWh
  • CPU耗电:21.05%*W=224mWh
  • Rest of SoC耗电:11.68%*W=107mWh
  • WIFI耗电:2.4%*W=26mWh
  • 内存耗电:3.19%*W=35mWh
  • GPU耗电:4.7%*W=57mWh
  • 平均电流约:273mA
  • 平均温度:32.2℃

通过ui自动化做电量测试的探索

我们知道锂电池充电分成三个阶段:预充,恒流,恒压。恒压阶段就是所谓的涓流充电。电量一般在80%左右往上,即进入恒压模式,此时充电速度会开始变慢,直到将电池充满。也就是说在电池电量低于80%时的恒流阶段,电量增加(充电速度)是匀速的。因此可以考虑将电池电量低于80%时,做UI自动化测试,然后将采集的电量数据除去充电补偿电量就可以得到测试阶段app的实际耗电量了。单位时间的充电补偿电量可以以同一测试手机连接同一电脑同一usb接口充电时电池容量从20%充电到70%的平均速度进行计算。

总结

iOS Diagnostics电量测试步骤:

1.装上对应的system debug证书;2.选定测试场景以及时长;3.记录开始时的剩余电量,执行测试,记录下哪个时间段对应的是哪个场景;3.执行测试完成后,精置半小时,取下系统的电量数据库,对该次测试的各个场景的耗电量做一个全面的评价。注意事项:1.给手机充放电,让手机剩余电量在我们预设的值——比如90%——每个场景测试开始时,保证手机都是这一电量;2.手机系统设置,一般要关注屏幕亮度、蓝牙、定位、通知消息、音量、其它后台应用等等,为排除对被测应用的影响,通常是全部关闭或调到最小即可。

iOS Diagnostics电量测试流程如下图:

参考文章

http://www.lyonanderson.org/blog/2014/02/06/ios-power-diagnostics/http://www.lyonanderson.org/blog/2014/11/05/ios-diagnostics-part-2/http://www.lyonanderson.org/blog/2014/11/13/ios-diagnostics-part-3/https://cloud.tencent.com/developer/article/1040416http://blog.csdn.net/m0_37890492/article/details/79103947