内存测试:
思路
- 目前做的是酒店APP,另下载安装几个个第三方酒店的APP以方便对比(相当于可以做竞品测试)
- 数据的获取来源是ADB底层命令,而且最好是不需要root权限,因为很多手机root很麻烦或者无法root
- 获取数据之后需要存储到excel表单,然后根据数据自动进行绘图形成简单的曲线图用于观察
- 记录数据的过程可以用Monkey操作/手工操作,后期也可以考虑加入自动化测试用例进行联动
疑问:
-
此APP是需要登录的,MONKEY测试过程中退出账号后无法再进入程序内部,不知道其他公司是如何避免的?
答:经咨询,目前常用两种做法:1. 让开发将退出按键给屏蔽掉 2.点击登录不检测账号和密码
一、运行Monkey
- 将白名单push到手机 ``` adb push E:\whitelist.txt data/local/tmp/
- 运行monkey
adb shell
monkey -pkg "packageName" -whitelist-file /data/local/tmp/whitelist.txt --throttle 200 -s 100 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes -v -v 15000 2>/sdcard/error.txt 1>/sdcard/info.txt
二、获取内存
移动端关注的是内存消耗,这个测试节点的设计目标是为了让应用不占用过多的系统资源,且及时释放内存,保障整个系统的稳定性,当然关于内存测试,在这里我们需要引入几个概念,
- 空闲状态
- 中等规格
- 满规格,
空闲状态:指打开应用后,点击home键让应用后台运行,此时应用处于的状态叫做空闲。 中等规格和满规格指的是对应用的操作时间的间隔长短不一,中等规格时间较长,满规格时间较短。
接下来我们说说在内存测试中,存在很多测试子项,如下清单所示
1.空闲状态下的应用内存消耗情况
2.中等规格状态下的应用内存消耗情况
3.满规格状态下的应用内存消耗情况
4.应用内存峰值情况
5.应用内存泄露情况
6.应用是否常驻内存
7.压力测试后的内存使用情况
说了一些关于内存测试方面的设定,接下来我们聊聊测试方法DIY,现在关于android内存测试的方法基本分为几类,
1.使用 android 本身提供的 ActivityManager.MemoryInfo() 方法获得(此方法请百度或google)此类第三方工具有如网易的Emmagee、安测试、腾讯的GT等
2.使用 android 提供的 adb shell dumpsys meminfo |grep packagename
>/address/mem.txt 来获取
3.使用 android 提供的 procrank
一般地,我们需要测试native heap, dalvik heap,Pss Total 内存(详解看下面的MemoryInfo解析)
这里我们详解一下 procrank 方法(批处理)
1.首先去google获取procrank、procmem、libpagemap.so 三个文件 .
2.然后push文件,
执行 adb push procrank /system/xbin
adb push procmem /system/xbin
adb push libpagemap.so /system/lib
3.赋权 adb shell chmod 6755 /system/xbin/procrank
adb shell chmod 6755 /system/xbin/procmem
adb shell chmod 6755 /system/lib/libpagemap.so ,
在开启工具记录 adb shell procrank |grep packagename >/address/procrank.txt
剩下的就是整理测试数据了
关于内存泄露方面的测试,可以通过几个方面来测试
1.通过monkey压力测试记录内存使用情况,分析数据曲线图及日志情况
2.通过eclipse上的mat+heap来分析存在内存泄露方面的节点
三、数据分析与内存详解
三、数据分析与内存详解
【将收集到的性能数据保存到excel中】
MemoryInfo解析:
Naitve Heap Size: 从mallinfo usmblks获得,代表最大总共分配空间
Native Heap Alloc: 从mallinfo uorblks获得,总共分配空间
Native Heap Free: 从mallinfo fordblks获得,代表总共剩余空间
Native Heap Size 约等于Native Heap Alloc + Native Heap Free
mallinfo是一个C库, mallinfo 函数提供了各种各样的通过C的malloc()函数分配的内存的统计信息。
Dalvik Heap Size:从Runtime totalMemory()获得,Dalvik Heap总共的内存大小
Dalvik Heap Alloc: Runtime totalMemory()-freeMemory() ,Dalvik Heap分配的内存大小。
Dalvik Heap Free:从Runtime freeMemory()获得,Dalvik Heap剩余的内存大小。
Dalvik Heap Size 约等于Dalvik Heap Alloc + Dalvik Heap Free
OtherPss, include Cursor,Ashmem, Other Dev, .so mmap, .jar mmap, .apk mmap, .ttf mmap, .dex mmap, Other mmap, Unkown统计信息都可以在process的smap文件看到。
Objects and SQL 信息都是从Android Debug信息中获得。
其他类型 smap 路径名称 描述
Cursor /dev/ashmem/Cursor Cursor消耗的内存(KB)
Ashmem /dev/ashmem 匿名共享内存用来提供共享内存通过分配一个多个进程
可以共享的带名称的内存块
Other dev /dev/ 内部driver占用的在 “Other dev”
.so mmap .so C 库代码占用的内存
.jar mmap .jar Java 文件代码占用的内存
.apk mmap .apk apk代码占用的内存
.ttf mmap .ttf ttf 文件代码占用的内存
.dex mmap .dex Dex 文件代码占用的内存
Other mmap 其他文件占用的内存
代码实现实例(抓取内存,python 2.7) :
class MemProfiler(BaseProfiler): def __init__(self, pid, adb, loghd): BaseProfiler.__init__(self, adb) self.appPid = pid # self.adb = adb self.loghd = loghd self.PSSList = [] self.NativeHeapList = [] self.DalvikHeapList = [] self.lastRecord = {} # 统计总内存,NATIVE内存,DALVIK内存
self.titile = ["总内存(MB)", "NativeHeap(MB)", "DalvikHeap(MB)"] # self.androidversion = 0 def init(self): self.androidversion = self.getAndroidVersion() def timeout(self, p): if p.poll() is None: self.loghd.info('appmonitor Error: process taking too long to complete--terminating') p.kill() def getProcessMem(self): if HEAP_PROFILE == False: return 0, 0, 0 cmdProcess = self.adb.cmd("shell", "dumpsys", "meminfo", self.appPid) output = "" my_timer = Timer(30, self.timeout, [cmdProcess]) try: my_timer.start() output = cmdProcess.communicate()[0].decode("utf-8").strip() except ValueError as err: self.loghd.info(err.args) finally: my_timer.cancel() m = re.search(r'TOTALs*(d+)', output) native = r'Native Heaps*(d+)' dalvik = r'Dalvik Heaps*(d+)' if int(self.androidversion) < 19: native = r'Native s*(d+)' dalvik = r'Dalvik s*(d+)' m1 = re.search(native, output) m2 = re.search(dalvik, output) PSS = float(m.group(1)) NativeHeap = float(m1.group(1)) DalvikHeap = float(m2.group(1)) return PSS, NativeHeap, DalvikHeap def profile(self): PSS, NativeHeap, DalvikHeap = self.getProcessMem() self.PSSList.append(round(PSS / 1024, 2)) self.NativeHeapList.append(round(NativeHeap / 1024, 2)) self.DalvikHeapList.append(round(DalvikHeap / 1024, 2)) return round(PSS / 1024, 2), round(NativeHeap / 1024, 2), round(DalvikHeap / 1024, 2)
[腾讯 TMQ][Android 场景化性能测试] UI 流畅度篇
https://testerhome.com/topics/10823
https://testerhome.com/topics/9513
【两句命令搞定移动端 (iOS 和 Android) 真机并发自动化测试】
github地址:
并发框架
MacacaLibrary
设计思路可以看:
浅谈测试工程化-以并发自动化框架为例