Android单元测试

来源:互联网 发布:三唑仑在淘宝能买来吗 编辑:程序博客网 时间:2024/06/13 17:09

       关于Android的单元测试,不仅仅可以确保某个模块的正确性,在比较大的项目当中,也可以保证整个项目的合理运行。其单元测试小到可以应用于一个Application,大到一个Activity中的内容。单元测试是否通过,在于给出一系列的输入,看输出的结果是否是我们所期望的。


       网上有许多关于单元测试的博客,大多都以demo的形式来呈现的,我们也不例外,这里只是简单介绍下有关于单元测试的一些基本内容,其实还有许多可以深入的地方,但我们这个例子只是对一些浅显内容的说明,辅助以一些注释。


首先最主要的是对配置文件的一些说明,在android工程中的AndroidMainFest.xml文件里,在<application 标签中加入<uses-library android:name="android.test.runner"这一句,相当于注册了相关的测试环境

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.cheng.myapplication" >    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity            android:name=".ResultActivity">        </activity>        <uses-library android:name="android.test.runner" />    </application></manifest>

我们先从一个小的Application开始,就简单弄个加法运算的函数吧,放在一个类之中

public class UnitTestApplication extends Application{    @Override    public void onCreate(){        super.onCreate();    }    @Override    public void onTerminate(){        super.onTerminate();    }    public int add(int firstNumber, int secondNumber){        return firstNumber + secondNumber;    }}


其add函数就是我们所定义的函数了,接下来为这个函数写一个单元测试的类


public class UnitTestApplicationTest extends ApplicationTestCase<UnitTestApplication> {    private UnitTestApplication unitTestApplication;    public UnitTestApplicationTest() {        //在构造函数中调用父类构造函数,参数为被测试的类        super(UnitTestApplication.class);    }    @Override    protected void setUp() throws Exception{        super.setUp();        createApplication();        //获取待测试的UnitTestApplication        unitTestApplication = getApplication();    }    //测试UnitTestApplication类中的add函数(注意测试函数的命名必须以test开头)    public void testadd(){        assertEquals(3, unitTestApplication.add(1, 2));    }}
这个类需要注意的几点:

1、测试类的构造函数调用父类的构造函数,其参数为被测试的类

2、在setUp函数中获取待测试的类

3、测试函数的命名必须以test开头





以上就是一个简单的application的测试类,下面我们来看看Activity的

我们这个Activity的功能十分简单,就一个输入用户名,密码的登录操作,界面截图过几天贴上

先来看看我们的xml布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin"    tools:context=".MainActivity"    android:orientation="vertical">    <EditText        android:id="@+id/user_name_et"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="输入用户名"/>    <EditText        android:id="@+id/pass_word_et"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="输入密码"/>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">                <Button            android:id="@+id/login_btn"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="登录"/>        <Button            android:id="@+id/clear_btn"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="清空"/>    </LinearLayout>    </LinearLayout>


再来看看我们的主类MainActivity.java

public class MainActivity extends ActionBarActivity implements View.OnClickListener{    private EditText mUserNameEt;    private EditText mPassWordEt;    private Button mLoginBtn;    private Button mClearBtn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findView();        setListener();    }    private void findView(){        mUserNameEt = (EditText)findViewById(R.id.user_name_et);        mPassWordEt = (EditText)findViewById(R.id.pass_word_et);        mLoginBtn = (Button)findViewById(R.id.login_btn);        mClearBtn = (Button)findViewById(R.id.clear_btn);    }    private void setListener(){        mLoginBtn.setOnClickListener(this);        mClearBtn.setOnClickListener(this);    }    @Override    public void onClick(View view){        int id = view.getId();        switch (id){            case R.id.login_btn:                Intent intent = new Intent(this, ResultActivity.class);                intent.putExtra("userName", mUserNameEt.getText().toString());                intent.putExtra("passWord", mPassWordEt.getText().toString());                startActivity(intent);                break;            case R.id.clear_btn:                mUserNameEt.setText("");                mPassWordEt.setText("");                break;            default:                break;        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }}


主类其实就是只做了三件事:1、绑定控件  2、设置点击响应事件  3、实现响应事件的具体操作

输入用户名和密码,点击登录,就会跳到下个页面ResultActivity.java,显示输入过的用户名和密码,点击清空,就会清空输入的用户名和密码


再来看看ResultActivity.java类和其xml文件吧

public class ResultActivity extends Activity{    private TextView mResultTv;    private String mUserName;    private String mPassWord;    @Override    protected void onCreate(Bundle savedInstanceState){        super.onCreate(savedInstanceState);        setContentView(R.layout.result_activity);        findView();        //获取从MainActivity传来的intent信息        Intent intent = getIntent();        mUserName = intent.getStringExtra("userName");        mPassWord = intent.getStringExtra("passWord");        mResultTv.setText(mUserName+ " "+mPassWord);    }    private void findView(){        mResultTv = (TextView)findViewById(R.id.result_tv);    }}


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:id="@+id/result_tv"        android:layout_width="match_parent"        android:layout_height="wrap_content" /></LinearLayout>


好了,接下来可以实现我们对这个MainActivity的测试类了

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity>{    private Instrumentation mInstrumentation;    private MainActivity mMainActivity;    private EditText mUserNameEt;    private EditText mPassWordEt;    private Button mLoginBtn;    private Button mClearBtn;    public MainActivityTest(){        super(MainActivity.class);    }    @Override    protected void setUp() throws Exception{        super.setUp();        setActivityInitialTouchMode(false);        mInstrumentation = getInstrumentation();        mMainActivity = getActivity();        mUserNameEt = (EditText)mMainActivity.findViewById(R.id.user_name_et);        mPassWordEt = (EditText)mMainActivity.findViewById(R.id.pass_word_et);        mLoginBtn = (Button)mMainActivity.findViewById(R.id.login_btn);        mClearBtn = (Button)mMainActivity.findViewById(R.id.clear_btn);    }    //输入相关信息    public void input(){        //用户名操作        mMainActivity.runOnUiThread(new Runnable() {            @Override            public void run() {                mUserNameEt.requestFocus();                mUserNameEt.performClick();            }        });        mInstrumentation.waitForIdleSync();        //输入用户名        sendKeys(KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_2, KeyEvent.KEYCODE_3);        //密码操作        mMainActivity.runOnUiThread(new Runnable() {            @Override            public void run() {                mPassWordEt.requestFocus();                mPassWordEt.performClick();            }        });        //输入密码        sendKeys(KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_2, KeyEvent.KEYCODE_3);    }    //测试输入信息    public void testInput(){        input();        assertEquals("123", mUserNameEt.getText().toString());        assertEquals("123", mPassWordEt.getText().toString());    }    //测试登录按钮    public void testLogin(){        input();        mInstrumentation.runOnMainSync(new Runnable() {            @Override            public void run() {                mLoginBtn.requestFocus();                mLoginBtn.performClick();            }        });    }    //测试清空按钮    public void testClear(){        input();        mInstrumentation.runOnMainSync(new Runnable() {            @Override            public void run() {                mClearBtn.requestFocus();                mClearBtn.performClick();            }        });        assertEquals("", mUserNameEt.getText().toString());        assertEquals("", mPassWordEt.getText().toString());    }}

其测试流程都按照我们实际的操作流程来进行,首先肯定是输入用户名和密码的操作,在input函数中,我调用了sendKeys函数,让系统测试的时候自动输入函数中的参数内容。

一共有三个测试函数,分别测试了输入的信息testInput,登录按钮testLogin,清空按钮testClear。

如果全部测试通过的话,那么系统的进度条会显示的是绿色样式,如果有其中一个不过,就说明输出的结果并不是正确的期望结果,进度条为红色样式。


此篇文章只浅显的讲了单元测试的一些基本流程,以后本人还会更加深入探索。






1 0
原创粉丝点击