Android應用性能測試

jopen 9年前發布 | 13K 次閱讀 Android 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);  
    }  
}  </pre> <p></p>


在這個類的構造函數中setAutomaticPerformanceSnapshots()為Instrumentation設置為開啟性能快照功能。

LaunchApp()方法中用于啟動相應的Activity, waitForIdleSync()方法則為等待Activity空閑時,即等待Activity啟動完畢。

二、編寫ActivityLaunchPerformanceTest類


    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);  
    }  
}  </pre><br />


</div> </div> </div> 這個類中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源碼。

五、對測試結果進行文本處理

1.進行格式化處理


adb  shell 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


    #!/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>"  
}  </pre></div>

</div> </div> 這里只提取需要的cpu_time,execution_time兩個字段的值,并將結果最終生成單元測試格式的xml文件

最終執行測試用例的命令如下:


 
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結果如下:


    <?xml version="1.0" encoding="UTF-8"?>  
    <testsuite>  
    <testcase name="execution_time" time="0.939  
    " />  
    <testcase name="cpu_time" time="0.85  
    " />  
    </testsuite>  
</div> </div>
六、Jenkins結果展示
測試用例可以使用命令行方式執行,因此也就可以使用Jenkins完成自動化測試,且對于生成的單元測試格式的xml報告,可以使用Jenkins的Performance Plugin插件進行圖表化展示:
 

來自:http://blog.csdn.net/hunterno4/article/details/23126453

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!