张亚洲 发表于 2015-1-6 08:44:00

【我分享】 Android应用性能测试

对于Web网页来说,页面的访问、加载速度对于用户体验来说是很重要的,而如果把Android中的每个Activity都看成是一个页面的话,Activity的启动速度凭主观的话是较难精确衡量的,因此如果可以测试每个Activity的启动速度或者获得其它基本指标并进行日常监测那就更好了。一、编写继承于Instrumentation类的LaunchPerformanceBase类




[*]/**
[*]* Base class for all launch performance Instrumentation classes.
[*]*/
[*]public class LaunchPerformanceBase extends Instrumentation {
[*]    public static final String TAG = "LaunchPerformanceBase";
[*]    protected Bundle mResults;
[*]    protected Intent mIntent;
[*]
[*]    /**
[*]    * Constructor.
[*]    */
[*]    public LaunchPerformanceBase() {
[*]      mResults = new Bundle();
[*]      mIntent = new Intent(Intent.ACTION_MAIN);
[*]      mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
[*]      setAutomaticPerformanceSnapshots();
[*]    }
[*]    /**
[*]    * Launches intent {@link #mIntent}, and waits for idle before
[*]    * returning.
[*]    */
[*]    protected void LaunchApp() {
[*]      startActivitySync(mIntent);
[*]      waitForIdleSync();
[*]    }
[*]
[*]    @Override
[*]    public void finish(int resultCode, Bundle results) {
[*]      super.finish(resultCode, results);
[*]    }
[*]}

在这个类的构造函数中setAutomaticPerformanceSnapshots()为Instrumentation设置为开启性能快照功能。
LaunchApp()方法中用于启动相应的Activity, waitForIdleSync()方法则为等待Activity空闲时,即等待Activity启动完毕。

二、编写ActivityLaunchPerformanceTest类

view plaincopyhttps://code.csdn.net/assets/CODE_ico.pnghttps://code.csdn.net/assets/ico_fork.svg


[*]public class ActivityLaunchPerformanceTest extends LaunchPerformanceBase {
[*]   /**
[*]      * Outfile argument name.
[*]      * This argument can be passed to the instrumentation using
[*]      <code>-e</code>.
[*]   */
[*]    private static final String launchActivityName = "launch_activity";
[*]    /**
[*]   * Output file name.
[*]   */
[*]    private String classNameForIntent;
[*]      private String DEFAULT_ACTIVITY = "SplashActivity";
[*]
[*]    /**
[*]    * Constructor.
[*]    */
[*]    public ActivityLaunchPerformanceTest() {
[*]      super();
[*]    }
[*]
[*]    @Override
[*]    public void onCreate(Bundle arguments) {
[*]      if ( arguments != null ) {
[*]            classNameForIntent = arguments.getString(launchActivityName);
[*]            }
[*]      if ( classNameForIntent == null ) {
[*]            classNameForIntent = DEFAULT_ACTIVITY ;
[*]            }
[*]      super.onCreate(arguments);
[*]      mIntent.setClassName("com.company.example",
[*]      "com.company.example.ui.activity." + classNameForIntent);
[*]      start();
[*]    }
[*]
[*]    /**
[*]    * Calls LaunchApp and finish.
[*]    */
[*]    @Override
[*]    public void onStart() {
[*]      super.onStart();
[*]      LaunchApp();
[*]      finish(Activity.RESULT_OK, mResults);
[*]    }
[*]}

这个类中onCreate()方法中传入要测试的Activity的名字。当开始测试时,Instrumentation启动,onStart方法执行时,运行LaunchApp()方法启动被测试的Activity.运行完成后finish。
Instrumentation退出,测试结束。

三、修改AndroidManifest.xml文件
在Manifest文件中增加Instrumentation申明




[*]<instrumentation
[*]      android:label="Activity Launch Performance"
[*]      android:name="com.company.example.test.performance.ActivityLaunchPerformanceTest"
[*]      android:targetPackage="com.company.example" />


四、运行Activity启动性能的测试用例



[*]adb shell am instrument -e launch_activity HomeActivity -w com.company.example.test/.performance.ActivityLaunchPerformanceTest

-e launch_activity参数后指定要测试的Activity名.测试结果大致如下:




[*]INSTRUMENTATION_RESULT: other_pss=7437
[*]INSTRUMENTATION_RESULT: java_allocated=4839
[*]INSTRUMENTATION_RESULT: global_freed_size=2583696
[*]INSTRUMENTATION_RESULT: native_private_dirty=1684
[*]INSTRUMENTATION_RESULT: native_free=81
[*]INSTRUMENTATION_RESULT: global_alloc_count=51608
[*]INSTRUMENTATION_RESULT: other_private_dirty=5468
[*]INSTRUMENTATION_RESULT: global_freed_count=18818
[*]INSTRUMENTATION_RESULT: sent_transactions=-1
[*]INSTRUMENTATION_RESULT: java_free=2784
[*]INSTRUMENTATION_RESULT: received_transactions=-1
[*]INSTRUMENTATION_RESULT: pre_sent_transactions=-1
[*]INSTRUMENTATION_RESULT: other_shared_dirty=7300
[*]INSTRUMENTATION_RESULT: pre_received_transactions=-1
[*]INSTRUMENTATION_RESULT: execution_time=749
[*]INSTRUMENTATION_RESULT: native_size=4772
[*]INSTRUMENTATION_RESULT: native_shared_dirty=620
[*]INSTRUMENTATION_RESULT: cpu_time=678
[*]INSTRUMENTATION_RESULT: java_private_dirty=320
[*]INSTRUMENTATION_RESULT: native_allocated=4690
[*]INSTRUMENTATION_RESULT: gc_invocation_count=5
[*]INSTRUMENTATION_RESULT: java_shared_dirty=1972
[*]INSTRUMENTATION_RESULT: global_alloc_size=3883815
[*]INSTRUMENTATION_RESULT: java_pss=2618
[*]INSTRUMENTATION_RESULT: java_size=7623
[*]INSTRUMENTATION_RESULT: native_pss=1699
[*]INSTRUMENTATION_CODE: -1

其中意义较大的结果有如cpu_time,execution_time分别代表Activity启动过程中进程占用的cpu时间与实际执行时间,单位毫秒。其它参数有兴趣的话可参照Instrumentation源码。

http://img.blog.csdn.net/20140407210238250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVudGVybm80/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

张亚洲 发表于 2015-1-6 08:44:17

五、对测试结果进行文本处理

1.进行格式化处理

view plaincopy在CODE上查看代码片派生到我的代码片

    adbshell am instrument -e launch_activity HomeActivity -w com.company.example.test/.performance.ActivityLaunchPerformanceTest | sed 's/=/:/' | sed 's/ //' | sed 's/\r//'

对测试结果进行=替换为:去除空格等格式化处理

2.编写gawk脚本,名字为txt_to_xml.gawk

view plaincopy在CODE上查看代码片派生到我的代码片

    #!/bin/bash
    BEGIN{
    print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    print "<testsuite>"
    FS=":"
    }
      
    $2 ~ /execution_time|cpu_time/{
    print "<testcase name=\"" $2 "\" time=\"" $NF*0.001
    print "\" />"
    }
    END{
    print "</testsuite>"
    }

这里只提取需要的cpu_time,execution_time两个字段的值,并将结果最终生成单元测试格式的xml文件

最终执行测试用例的命令如下:

view plaincopy在CODE上查看代码片派生到我的代码片

    adb shell am instrument -e launch_activity HomeActivity -w com.company.example.test/.performance.ActivityLaunchPerformanceTest | sed 's/=/:/' | sed 's/ //' | sed 's/\r//' | gawk -f txt_to_xml.gawk > TEST-HomeActivity.xml

得到的xml结果如下:

view plaincopy在CODE上查看代码片派生到我的代码片

    <?xml version="1.0" encoding="UTF-8"?>
    <testsuite>
    <testcase name="execution_time" time="0.939
    " />
    <testcase name="cpu_time" time="0.85
    " />
    </testsuite>


六、Jenkins结果展示
测试用例可以使用命令行方式执行,因此也就可以使用Jenkins完成自动化测试,且对于生成的单元测试格式的xml报告,可以使用Jenkins的Performance Plugin插件进行图表化展示:

风在吹 发表于 2015-1-6 12:41:16

good,不错

foyyti008 发表于 2015-1-6 13:41:39

:lol:lol:lol:lol:lol:lol
页: [1]
查看完整版本: 【我分享】 Android应用性能测试