移动端性能测试方案

时间:2024-03-10 08:21:25

一、移动端性能测试指标
性能测试需要收集的指标项包含:页面时长、电量、CPU、内存、流量、包大小。
目前阶段主要关注的指标项:页面时长、电量

二、指标收集&分析方法

  • 页面时长:RD跟进所需场景进行埋点并上报Omega进行场景化、链路化统计分析
  • 电量:Android使用batterystatus进行电量收集、使用Battery Historian进行电量数据分析;iOS diagnostics 方案可行性待定

三、电量测试方法

step1:打开App执行性能场景

step2:性能场景执行完毕后,通过adb batterystats 命令获取电量日志

step3:导出电量报告bugreport,借助Battery Historian 进行可视化分析

Battery Historian工具介绍: https://github.com/google/battery-historian

四、电量度量标准

五、性能测试场景

六、测试前提

在测试之前,确保以下测试环境要素都已满足(适用Android/iOS):

七、测试机型

八、测试版本

九、QA人员

十、性能测试报告

 

如何获取手机性能测试数据FPS

本人在做APP性能测试的过程中,为了测试APP在各个场景下的流畅度,需要收集手在各个运行场景下的fps数据,经常查资料,使用的是adb shell命令:

adb shell dumpsys gfxinfo 包名
分享代码,供大家参考。
测试方法:

1        Fps fps = new Fps();
2            fps.start();
3            //do something
4            fps.stopFps();
5            fps.join();

多线程类的代码:

  1package monkeytest;
2
3import java.io.BufferedReader;
4import java.io.IOException;
5import java.io.InputStream;
6import java.io.InputStreamReader;
7import java.util.ArrayList;
8import java.util.List;
9import java.util.Random;
10import java.util.regex.Matcher;
11import java.util.regex.Pattern;
12import source.AppLocalMySql;
13import source.Common;
14
15public class Fps extends Thread {
16    private boolean KEY = true;
17    private static String testName = "normal";
18    private int mark = Common.mark;
19
20    @Override
21    public void run() {
22        while (KEY) {
23            execCmdAdb("adb shell dumpsys gfxinfo com.happyjuzi.apps.juzi");
24            Common.getInstance().sleep(5000);
25        }
26    }
27
28    public int getMatcher(String text, Pattern pattern) {
29        Pattern newattern = Pattern.compile(pattern.toString().trim());
30        Matcher matcher = newattern.matcher(text);
31        List<String> numbers = new ArrayList<>();
32        while (matcher.find()) {
33            String number = matcher.group(0);
34            numbers.add(number);
35        }
36        double result = 0;
37        for (int i = 0; i < numbers.size(); i++) {
38            double num = Common.getInstance().changeStringToDouble(numbers.get(i));
39            result += num;
40        }
41        int total = (int) result + new Random().nextInt(2);
42        return total;
43    }
44
45    /**
46     * 结束线程
47     */
48    public void stopFps() {
49        this.KEY = false;
50    }
51
52    /**
53     * 执行cmd命令
54     * 
55     * @param cmd
56     *            命令
57     */
58    public void execCmdAdb(String cmd) {
59        Pattern pattern = Pattern.compile(" ([0-9]{1,2}+\\.[0-9]{2})");
60        output("正在执行:" + cmd);
61        String OSname = System.getProperty("os.name");
62        try {
63            Process p = null;
64            if (OSname.contains("Mac")) {
65                p = Runtime.getRuntime().exec(Common.ADB_PATH + cmd);
66            } else {
67                p = Runtime.getRuntime().exec("cmd /c " + cmd);
68            }
69            // 正确输出流
70            InputStream input = p.getInputStream();// 创建并实例化输入字节流
71            BufferedReader reader = new BufferedReader(new InputStreamReader(input));// 先通过inputstreamreader进行流转化,在实例化bufferedreader,接收内容
72            String line = "";
73            while ((line = reader.readLine()) != null) {// 循环读取
74                if (line.startsWith("   ")) {
75                    Matcher matcher = pattern.matcher(line);
76                    if (matcher.find()) {
77                        AppLocalMySql.getInstance().saveFps(testName, mark);
78                        getMatcher(line, pattern);// 输出
79                    }
80                }
81            }
82            reader.close();// 此处reader依赖于input,应先关闭
83            input.close();
84            // 错误输出流
85            InputStream errorInput = p.getErrorStream();// 创建并实例化输入字节流
86            BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorInput));// 先通过inputstreamreader进行流转化,在实例化bufferedreader,接收内容
87            String eline = "";
88            while ((eline = errorReader.readLine()) != null) {// 循环读取
89                System.out.println(eline);// 输出
90                Common.getInstance().saveToFile(eline, "runlog.log");// 保存,false表示不覆盖
91            }
92            errorReader.close();// 此处有依赖关系,先关闭errorReader
93            errorInput.close();
94        } catch (IOException e) {
95            output("执行" + cmd + "失败!");
96            e.printStackTrace();
97        }
98    }
99
100    public void output(String text) {
101        System.out.println(text);
102    }
103
104    public void output(Object... object) {
105        if (object.length == 1) {
106            output(object[0].toString());
107            return;
108        }
109        for (int i = 0; i < object.length; i++) {
110            System.out.println("第" + (i + 1) + "个:" + object[i]);
111        }
112    }
113}

往期文章精选

  1. java一行代码打印心形

  2. Linux性能监控软件netdata中文汉化版

  3. 接口测试代码覆盖率(jacoco)方案分享

  4. 性能测试框架

  5. 如何在Linux命令行界面愉快进行性能测试

  6. 图解HTTP脑图

  7. 写给所有人的编程思维

  8. 测试之JVM命令脑图

  9. 将json数据格式化输出到控制台

  10. 如何测试概率型业务接口

  11. “双花”BUG的测试分享

  12. 将swagger文档自动变成测试代码

来源公众号:

FunTester