静置耗流量测试方法
主要步骤(一)
1、静置耗流量,测试前手机与PC端Fiddler建立连接,用来待机测试的过程中同时用电脑端抓包;
2、adb shell ps | grep package_name :获取应用PID
3、adb shell cat /proc/PID/status :获取应用UID
4、adb shell cat /proc/net/xtqtaguid/stats|grep UID|awk '{rxbytes+=$6}END{print rx_bytes} :tcp、udp接收数据流量和
5、adb shell cat /proc/net/xtqtaguid/stats|grep UID|awk '{txbytes+=$8}END{print tx_bytes} :tcp、udp发送的数据流量和
6、第4步和第5步的数值相加即为当前应用从使用到现在消耗的流量,单位为B,除以1024换算为KB;
7、测试应用静置耗流量的时候,设定好初始条件(如操作完主要网络业务后,放置入后台开始待机),执行前6步,记录当前应用从使用到现在消耗的流量;待机12小时完成后,再次执行前6步获取应用从使用到现在消耗的流量,二次测试数据相减获取应用待机这段时间内获取的流量消耗,就是静置这段时间内应用消耗的流量。
备注:静置耗流量一般晚上测试,应用进入后台待机,统计12小时左右的静置流量消耗,通常这部分消耗与发送数据包或者长连接相关
方法(一):集成一些脚本处理
其基本思路是:测试单项业务功能前,(比如更换用户个人资料图像)运行脚本获取当应用已经消耗的累计流量,操作完业务操作后,再次运行脚本获取已消耗的累计流量,前后两次流量做差值即为当前业务操作下的流量消耗;如果是WIFI下操作,则统计WIFI下的流量消耗,如果是移动网络,则统计移动网络下的流量消耗;
package UItest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.rmi.server.UID;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JavaPerformanceTest {
public static void main(String[] args) throws Exception{
// String res = testGetPackage();
// String res = "com.xdja.HDSafeEMailClient";
// String res = "com.xdja.ryhzw";
// String res = "com.tencent.mm";
// String res = "com.tencent.mobileqq";
// String res = "com.xdja.eoa";
// String res = "com.kingsoft.email";
String res = "com.xdja.jxclient";
getFlowWifi(res);
getFlowdata(res);
}
/**
* getuid:当前应用WIFI下流量消耗的总量统计,用于测试静置流量消耗,二次做一下差值即可
* @author lzz
*
*/
public static void getFlowWifi(String pkg){
String uid = null;
try {
uid = getuid(pkg);
System.out.println("应用"+pkg+"的UID信息是:"+uid);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
float flow = 0;
try {
flow = getliuliangwifi(uid);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("从开机到现在累计的流量消耗,静置耗流量需要测试前后收集二次数据并做差值");
System.out.println("当前被测应用为:"+pkg);
System.out.println("当前应用WIFI流量累计总消耗是:"+flow+"单位:Byte");
DecimalFormat df = new DecimalFormat("0.00");//添加数据格式化对象
System.out.println("当前应用WIFI流量累计总消耗是:"+df.format(flow/1024)+"单位:KB");
System.out.println("当前应用WIFI流量累计总消耗是:"+df.format(flow/1024/1024)+"单位:MB.\n\n");
}
/**
* getuid:当前应用数据下流量消耗的总量统计,用于测试静置流量消耗,二次做一下差值即可
* @author lzz
*
*/
public static void getFlowdata(String pkg){
String uid = null;
try {
uid = getuid(pkg);
System.out.println("应用"+pkg+"的UID信息是:"+uid);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
float flow = 0;
try {
flow = getliulianggprs(uid);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("从开机到现在累计的流量消耗,静置耗流量需要测试前后收集二次数据并做差值");
System.out.println("当前被测应用为:"+pkg);
System.out.println("当前应用数据流量累计总消耗是:"+flow+"单位:Byte");
DecimalFormat df = new DecimalFormat("0.00");//添加数据格式化对象
System.out.println("当前应用数据流量累计总消耗是:"+df.format(flow/1024)+"单位:KB");
System.out.println("当前应用数据流量累计总消耗是:"+df.format(flow/1024/1024)+"单位:MB.\n\n");
}
/**
* getuid:根据应用包名获取Android APP uid信息
* @author lzz
*
*/
public static String getuid(String packagename) throws Exception
{
Process p=Runtime.getRuntime().exec("adb shell dumpsys package "+packagename+" |grep userId");
java.io.InputStream in=p.getInputStream();
InputStreamReader ir=new InputStreamReader(in);
BufferedReader br=new BufferedReader(ir);
// System.out.println(br.readLine());//br.readLine()一旦被执行一次,则影响下一次的执行结果
String uid=br.readLine().split("=")[1].split(" ")[0];
return uid;
}
/**
* PID:根据应用包名获取Android APP PID信息
* @author lzz
*
*/
public static String PID(String PackageName) throws IOException {
String PID=null;
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("adb shell ps |grep "+PackageName);
try {
if (proc.waitFor() != 0) {
System.err.println("exit value = " + proc.exitValue());
}
BufferedReader in = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
StringBuffer stringBuffer = new StringBuffer();
String line = null;
while ((line = in.readLine()) != null) {
stringBuffer.append(line+" ");
}
String str1=stringBuffer.toString();
String str2=str1.substring(str1.indexOf(" "+PackageName)-46,str1.indexOf(" "+PackageName));
String str3 =str2.substring(0,7);
str3 = str3.trim();
PID=str3;
} catch (InterruptedException e) {
System.err.println(e);
}finally{
try {
proc.destroy();
} catch (Exception e2) {
}
}
return PID;
}
/**
* package:根据应用置顶app包名,暂时还未调试好
* @author lzz
*
*/
public static String getPackage() throws Exception
{
Process proc=Runtime.getRuntime().exec("adb shell dumpsys window |grep mFocus");
String str1 = "";
try {
if (proc.waitFor() != 0) {
System.err.println("exit value = " + proc.exitValue());
}
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
StringBuffer stringBuffer = new StringBuffer();
String line = null;
while ((line = in.readLine()) != null) {
stringBuffer.append(line+" ");
}
str1=stringBuffer.toString();
// System.out.println(str1);
}catch (InterruptedException e) {
System.err.println(e);
}finally{
try {
proc.destroy();
} catch (Exception e2) {
}
}
return str1;
}
/**
* package:获取应用流量消耗,WIFI的流量消耗,累计到这段时间内,WIFI消耗的总流量。
* @author lzz
*
*/
public static float getliuliangwifi(String uid) throws IOException
{
Process p=Runtime.getRuntime().exec("adb shell cat /proc/net/xt_qtaguid/stats |grep "+uid+" |grep wlan0");
java.io.InputStream in=p.getInputStream();
InputStreamReader ir=new InputStreamReader(in);
BufferedReader br=new BufferedReader(ir);
String str;
float total=0;
while((str=br.readLine())!=null)
{
total=total+Integer.parseInt(str.split(" ")[5])+Integer.parseInt(str.split(" ")[7]);
str=br.readLine();
}
return total;
}
/**
* getCmdOut:以字符串的形式输出Cmd命令的结果
* @author lzz
*
*/
public static String getCmdOut(String cmd) throws IOException
{
Process p=Runtime.getRuntime().exec(cmd);
java.io.InputStream in=p.getInputStream();
InputStreamReader ir=new InputStreamReader(in);
BufferedReader br=new BufferedReader(ir);
String str;
StringBuffer stringBuffer = new StringBuffer();//字符串接收对象
while((str=br.readLine())!=null)
{
stringBuffer.append(str);
str=br.readLine();
}
str = stringBuffer.toString();
return str;
}
/**
* package:获取应用流量消耗,GPRS的流量消耗,累计到这段时间内,数据消耗的总流量。单位为Byte.
* @author lzz
*
*/
public static float getliulianggprs(String uid) throws IOException
{
Process p=Runtime.getRuntime().exec("adb shell cat /proc/net/xt_qtaguid/stats | grep "+uid+" |grep rmnet");
java.io.InputStream in=p.getInputStream();
InputStreamReader ir=new InputStreamReader(in);
BufferedReader br=new BufferedReader(ir);
String str;
float total=0;
while((str=br.readLine())!=null)
{
total=total+Integer.parseInt(str.split(" ")[5])+Integer.parseInt(str.split(" ")[7]);
str=br.readLine();
}
return total;
}
/**
* testGetPackage:点击打开当前应用,以获取当前应用的包名
* @author lzz
*
*/
public static String testGetPackage(){
String pkg= "";
try {
// Process process = Runtime.getRuntime().exec("ipconfig /all");
Process process = Runtime.getRuntime().exec("adb shell dumpsys window |grep mFocus");
// System.out.println(process);
// Process p = null;
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;//初始化变量
String str = "";
while ((line = input.readLine()) != null) {
// System.out.println(line);
str =str+line;
}
// System.out.println(str);
String pattern = "(com.*?)/";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(str);
if (m.find( )) {
// System.out.println("Found value: " + m.group(0) );
// System.out.println("Found value: " + m.group(1) );
pkg = m.group(1);
} else {
System.out.println("NO MATCH");
}
} catch (IOException e) {
e.printStackTrace();
}
return pkg;
}
}
fiddler的使用步骤
1、首先,确保安装 Fiddler 的电脑和你的手机在同一局域网内,因为Fiddler只是一个代理,需要将手机的代理指向 PC 机,不能互相访问是不行的。(或者在PC机上开启一个热点WIFI)
2、开启Fiddler的远程连接,Fiddler 主菜单 Tools → Fiddler Options…→ Connections页签,选中Allowremote computers to connect。
3、开启好远程连接之后,重启Fiddler,不然就不会更新你刚开启的远程配置
4、设置手机连接PC端热点WIFI,长按手机端WIFI修改网络,选择高级选项配置手机端WIFI代理,例如获取PC的IP地址192.168.2.121(打开cmd,输入ipconfig来查看电脑端的本地ip),配置手机端ip为是:192.168.2.121(长按连接的WIFI网络-高级选项-输入代理ip地址和端口,默认为8888的端口);
5、关闭手机端第三方联网应用和PC机联网应用,打开被测APP进行操作,可以开始抓包了。
6、如果手机端没有证书,请安装证书后使用。手机端访问“192.168.2.121:8888”(PC的ip地址和端口号),如果出现响应页面说明成功,操作手机端联网APP,可以在fiddler中看到抓取的数据包详情。
网络请求测试和说明
测试步骤和方法:
1、一般是进入有网络请求的页面,比如:进入个人中心页面、进入某展示页面等,则查看这段时间fiddler抓取的数据包,看是否有重复的网络请求(url及数据返回结果一样,则可能是重复请求);如右上图展示了在进入某页面时存在两个一样的网络请求。
2、反复进入某一有网络请求页面,比如:进入个人中心页面,如果每次进入都会请求相同的数据,则需要怀疑,逻辑是否正常,是否应该将数据缓存到本地,减少网络请求的个数。如右中图展示了请求了两张一样的图片(虽然图片的名称不一样,但是经比对是一样的)。
3、服务器有缓存,客户端没有使用;可以通过查看数据包的request headers 和response headers信息,第一次请求,如果在response headers中存在Entity的数据信息,说明服务器端有缓存信息;第二次请求,假如request headers 中没有带上etag和last-modified 字段,说明客户端并没有利用缓存,会额外的消耗流量。见下图