Android應用效能測試
阿新 • • 發佈:2018-12-31
對於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類
這個類中onCreate()方法中傳入要測試的Activity的名字。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); } }
當開始測試時,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>"
}
這裡只提取需要的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>
六、Jenkins結果展示
測試用例可以使用命令列方式執行,因此也就可以使用Jenkins完成自動化測試,且對於生成的單元測試格式的xml報告,可以使用Jenkins的Performance Plugin外掛進行圖表化展示: