• <只看这个就够了。。。>Android自动化测试及性能优化


     

    Android自动化测试及性能优化

    分类: Android Java Tools

    软件自动化测试对于程序员来说能够确保软件开发的质量和效率。在Android编程中,Android集成了Junit单元测试框架,因此我们可以通过Junit来进行单元测试以及自动化测试。

    1、引入Junit测试框架

    在Manifest.xml配置文件中,我们需要引入Junit测试框架,因此需要在配置文件中添加如下代码:

    在<application>标签中添加Junit测试库:

    [html] view plaincopy
     
    1. <uses-library android:name="android.test.runner" />  


    在<manifest>标签中添加以下代码:

    [html] view plaincopy
     
    1. <instrumentation  
    2.     android:name="android.test.InstrumentationTestRunner"  
    3.     android:label="Tests for My App"  
    4.     android:targetPackage="com.jony.androidtestdemo" />  

    其中android:name="android.test.InstrumentationTestRunner"表示引入Android测试类

    android:label="Tests for My App"该属性的具体内容根据实际情况自行定义

    android:targetPackage="com.jony.androidtestdemo"该属性定义了需要测试的包名

    至此,进行单元测试需要配置的工作就全部完成了。接下来简单写几个测试用的Activity——模拟实现用户登录过程

    2、业务代码编写

    MainActivity.java主要作用是实现Activity界面的跳转,通过点击界面上的Button按钮,跳转到用户登录界面;

    LoginActivity.java主要作用是接收用户输入的用户名和密码;

    HomeActivity.java用户登录成功界面。

    以上三个界面的逻辑非常简单,本文重点在于讲解Android自动化测试以及性能优化,因此复杂的业务逻辑在此就不做过多介绍。

    3、单元测试

    在进行单元测试前,大家可能最关注的是:怎样获得Activity的实例?

    的确,这个问题是我们必须要关心的。既然我们能想到的问题,想必Android的大牛们已经给我们提供了怎么获得Activity实例的方法了。
    在Android单元测试中,我们只要继承ActivityInstrumentationTestCase2 类,在其构造函数中传入需要测试的Activity,就能通过getActivity()方法获得我们需要测试的Activity的实例,具体代码如下所示:

    MainActivity.java的测试代码如下所示:

    [java] view plaincopy
     
    1. package com.jony.androidtestdemo.test;  
    2.   
    3. import android.app.Instrumentation;  
    4. import android.test.ActivityInstrumentationTestCase2;  
    5. import android.test.UiThreadTest;  
    6. import android.test.suitebuilder.annotation.Suppress;  
    7. import android.util.Log;  
    8. import android.view.View;  
    9.   
    10. import com.jony.androidtestdemo.MainActivity;  
    11. import com.jony.androidtestdemo.R;  
    12.   
    13. public class MainActivityTest extends  
    14.         ActivityInstrumentationTestCase2<MainActivity> {  
    15.   
    16.     private static final String TAG = "MainActivityTest";  
    17.   
    18.     private Instrumentation mInstrument;  
    19.   
    20.     private MainActivity mActivity;  
    21.   
    22.     private View mToLoginView;  
    23.   
    24.     public MainActivityTest() {  
    25.         super(MainActivity.class);  
    26.     }  
    27.   
    28.     @Override  
    29.     public void setUp() throws Exception {  
    30.         super.setUp();  
    31.         mInstrument = getInstrumentation();  
    32.         // 启动被测试的Activity  
    33.         mActivity = getActivity();  
    34.         mToLoginView = mActivity.findViewById(R.id.to_login);  
    35.     }  
    36.   
    37.     public void testPreConditions() {  
    38.         // 在执行测试之前,确保程序的重要对象已被初始化  
    39.         assertTrue(mToLoginView != null);  
    40.     }  
    41.   
    42.     // mInstrument.runOnMainSync(new Runnable() {  
    43.   
    44.     // public void run() {  
    45.   
    46.     // mToLoginView.requestFocus();  
    47.   
    48.     // mToLoginView.performClick();  
    49.   
    50.     // }  
    51.   
    52.     // });  
    53.   
    54.     @UiThreadTest  
    55.     public void testToLogin() {  
    56.         // @UiThreadTest注解使整个方法在UI线程上执行,等同于上面注解掉的代码  
    57.         mToLoginView.requestFocus();  
    58.         mToLoginView.performClick();  
    59.   
    60.     }  
    61.   
    62.     @Suppress  
    63.     public void testNotCalled() {  
    64.         // 使用了@Suppress注解的方法不会被测试  
    65.         Log.i(TAG, "method 'testNotCalled' is called");  
    66.     }  
    67.   
    68.     @Override  
    69.     public void tearDown() throws Exception {  
    70.         super.tearDown();  
    71.     }  
    72. }  

    LoginActivity.java测试代码如下所示:

    [java] view plaincopy
     
    1. package com.jony.androidtestdemo.test;  
    2.   
    3. import android.app.Instrumentation;  
    4. import android.test.ActivityInstrumentationTestCase2;  
    5. import android.util.Log;  
    6. import android.view.KeyEvent;  
    7. import android.view.View;  
    8. import android.widget.EditText;  
    9. import com.jony.androidtestdemo.LoginActivity;  
    10. import com.jony.androidtestdemo.R;  
    11.   
    12. public class LoginActivityTest extends  
    13.         ActivityInstrumentationTestCase2<LoginActivity> {  
    14.   
    15.     private static final String TAG = "LoginActivityTest";  
    16.     private Instrumentation mInstrument;  
    17.   
    18.     private LoginActivity mActivity;  
    19.   
    20.     private EditText mUsernameView;  
    21.   
    22.     private EditText mPasswordView;  
    23.   
    24.     private View mSubmitView;  
    25.   
    26.     private View mResetView;  
    27.   
    28.     public LoginActivityTest() {  
    29.         super(LoginActivity.class);  
    30.     }  
    31.   
    32.     @Override  
    33.     public void setUp() throws Exception {  
    34.         super.setUp();  
    35.         /* 
    36.          * 要向程序发送key事件的话,必须在getActivity之前调用该方法来关闭touch模式 
    37.          * 否则key事件会被忽略 
    38.          */  
    39.         setActivityInitialTouchMode(false);  
    40.         mInstrument = getInstrumentation();  
    41.         mActivity = getActivity();  
    42.         Log.i(TAG, "current activity: " + mActivity.getClass().getName());  
    43.         mUsernameView = (EditText) mActivity.findViewById(R.id.username);  
    44.         mPasswordView = (EditText) mActivity.findViewById(R.id.password);  
    45.         mSubmitView = mActivity.findViewById(R.id.submit);  
    46.         mResetView = mActivity.findViewById(R.id.reset);  
    47.   
    48.     }  
    49.   
    50.     public void testPreConditions() {  
    51.         assertTrue(mUsernameView != null);  
    52.         assertTrue(mPasswordView != null);  
    53.         assertTrue(mSubmitView != null);  
    54.         assertTrue(mResetView != null);  
    55.   
    56.     }  
    57.   
    58.     public void testInput() {  
    59.         input();  
    60.         assertEquals("1231", mUsernameView.getText().toString());  
    61.         assertEquals("11", mPasswordView.getText().toString());  
    62.   
    63.     }  
    64.   
    65.     public void testSubmit() {  
    66.         input();  
    67.         mInstrument.runOnMainSync(new Runnable() {  
    68.             public void run() {  
    69.                 mSubmitView.requestFocus();  
    70.                 mSubmitView.performClick();  
    71.             }  
    72.         });  
    73.   
    74.     }  
    75.   
    76.     public void testReset() {  
    77.         input();  
    78.         mInstrument.runOnMainSync(new Runnable() {  
    79.             public void run() {  
    80.                 mResetView.requestFocus();  
    81.                 mResetView.performClick();  
    82.             }  
    83.         });  
    84.         assertEquals("", mUsernameView.getText().toString());  
    85.         assertEquals("", mPasswordView.getText().toString());  
    86.   
    87.     }  
    88.   
    89.     @Override  
    90.     public void tearDown() throws Exception {  
    91.         super.tearDown();  
    92.     }  
    93.   
    94.     private void input() {  
    95.         mActivity.runOnUiThread(new Runnable() {  
    96.             public void run() {  
    97.                 mUsernameView.requestFocus();  
    98.             }  
    99.         });  
    100.        // 因为测试用例运行在单独的线程上,这里最好要  
    101.         // 同步application,等待其执行完后再运行  
    102.         mInstrument.waitForIdleSync();  
    103.         sendKeys(KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_2,  
    104.         KeyEvent.KEYCODE_3);  
    105.         // 效果同上面sendKeys之前的代码  
    106.         mInstrument.runOnMainSync(new Runnable() {  
    107.             public void run() {  
    108.                 mPasswordView.requestFocus();  
    109.             }  
    110.         });  
    111.         sendKeys(KeyEvent.KEYCODE_1);  
    112.     }  
    113.   
    114. }  

    HomeActivity.java测试代码如下所示:

    [java] view plaincopy
     
    1. package com.jony.androidtestdemo.test;  
    2.   
    3. import android.content.Intent;  
    4. import android.test.ActivityUnitTestCase;  
    5. import android.widget.TextView;  
    6.   
    7. import com.jony.androidtestdemo.HomeActivity;  
    8. import com.jony.androidtestdemo.R;  
    9.   
    10. public class HomeActivityTest extends ActivityUnitTestCase<HomeActivity> {  
    11.     private static final String TAG = "HomeActivityTest";  
    12.     private static final String LOGIN_CONTENT = "username:1231 password:11";  
    13.     private HomeActivity mHomeActivity;  
    14.     private TextView mLoginContentView;  
    15.     public HomeActivityTest() {  
    16.         super(HomeActivity.class);  
    17.     }  
    18.   
    19.     @Override  
    20.     public void setUp() throws Exception {  
    21.         super.setUp();  
    22.         Intent intent = new Intent();  
    23.         intent.putExtra(HomeActivity.EXTRA_USERNAME, "1231");  
    24.         intent.putExtra(HomeActivity.EXTRA_PASSWORD, "11");  
    25.         // HomeActivity有extra参数,所以我们需要以intent来启动它  
    26.         mHomeActivity = launchActivityWithIntent("com.jony.androidtestdemo",  
    27.                 HomeActivity.class, intent);  
    28.         mLoginContentView = (TextView) mHomeActivity  
    29.                 .findViewById(R.id.login_content);  
    30.     }  
    31.   
    32.     public void testLoginContent() {  
    33.         assertEquals(LOGIN_CONTENT, mLoginContentView.getText().toString());  
    34.     }  
    35.   
    36.     @Override  
    37.     public void tearDown() throws Exception {  
    38.         super.tearDown();  
    39.     }  
    40.   
    41. }  

    到此,简单的测试代码就完成了,接下来就是验证代码能否正常运行。

    首先,需要将Android应用程序安装到手机或者模拟器上面才能运行测试代码,打开Eclipse的Outline窗口,选中需要测试的方法,单击右键选择Run As-->Android Junit Test

    如果出现下图的绿色状态栏则说明运行成功。

    Android性能测试

    在Android的SDK的tools 目录中,Android为我们提供了一个性能测试工具traceview,通过traceview功能我们能够确切了解每个方法执行的时间,调用次数以及递归调用测试等信息。通过分析各方法的调用时间可以了解系统的瓶颈,提升系统性能。

    使用方法:

    在需要进行性能分析的Activity中加入以下代码(一般在Activity的onCreate()方法中添加):

    [java] view plaincopy
     
    1. Debug.startMethodTracing("jonytest");//jonytest.trace  

    在onDestroy()方法中添加:

    [java] view plaincopy
     
    1. Debug.stopMethodTracing();// 停止数据采集  

    运行程序,当程序运行到该Activity是,系统会自动记录该Activity的所调用的所有方法的信息,并生成jonytest.trace文件保存在SDcard中。将该文件导出到电脑C盘,运行以下命令:traceview jonytest.trace 系统将会弹出如图所示窗口(可以在Find窗口查找具体方法(目前只支持小写)):

    至此,Android单元测试和系统优化已经给大家介绍完了,知识融会贯通,希望对大家有所帮助。

  • 相关阅读:
    【转载】JavaScript变量: 变量命名原则
    【转载】mysql运行报【The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone...】的解决方法
    Java Web 环境搭建
    原生JS消息提示插件Message.js
    SQL Server 参数嗅探问题
    根据表名和列名获取关联index的创建脚本
    mongodb快速均衡导入数据
    index optimize
    PG Foreign key 外键
    无密码登陆
  • 原文地址:https://www.cnblogs.com/duanweishi/p/4605422.html
Copyright © 2020-2023  润新知