上篇我们讲到了普通的类测试,这次我们来关注下有控件的Android Activity是如何进行单元测试的。
首先我们写一个简单的Activity ,叫CalculateActivity,很简单里面有两个输入框,一个按钮,点击按钮就能得到两个输入框中输入数字的求和。
布局文件res/layout/main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/edit01"
android:inputType="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/plus"
android:gravity="center_horizontal"
/>
<EditText
android:id="@+id/edit02"
android:inputType="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/btnSum"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn_sum"
/>
<TextView
android:id="@+id/txtResult"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
res/values/strings.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, CalculateActivity!</string>
<string name="app_name">CalculateActivity</string>
<string name="btn_sum">相加</string>
<string name="plus">+</string>
</resources>
src/com.waitingfy.android/CalculateActivity.java
package com.waitingfy.android;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class CalculateActivity extends Activity {
/** Called when the activity is first created. */
EditText editText01;
EditText editText02;
Button buttonSum;
TextView resultTextView;
MyClass myClass;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myClass = new MyClass();
editText01 = (EditText)findViewById(R.id.edit01);
editText02 = (EditText)findViewById(R.id.edit02);
resultTextView = (TextView)findViewById(R.id.txtResult);
buttonSum = (Button)findViewById(R.id.btnSum);
buttonSum.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int a =Integer.parseInt( editText01.getText().toString());
int b =Integer.parseInt( editText02.getText().toString());
//把结果计算出来
resultTextView.setText(myClass.sum(a, b)+"");
}
});
}
}
src/com.waitingfy.android/MyClass.java
package com.waitingfy.android;
public class MyClass {
public int sum(int a,int b) {
return a + b;
}
}
被测试的Activity写好了,输进去几个值计算好像没有问题,我们来用单元测试来测试一下。
我们建立一个AndroidTest的项目,叫CalculateActivityTest。建立的过程跟上篇提到的一样。
建立好后,我们新建一个文件,叫TestCalculateActivity.java,里面的内容如下:
package com.waitingfy.android.test;
import com.waitingfy.android.CalculateActivity;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class TestCalculateActivity extends ActivityInstrumentationTestCase2<CalculateActivity>{
//好像必须要一个无参数或一个参数的构造函数
public TestCalculateActivity() {
super("com.waitingfy.android", CalculateActivity.class);
}
private CalculateActivity mActivity;
private EditText mEditText01;
private EditText mEditText02;
private Button mButton;
private TextView mView;
@Override
protected void setUp() throws Exception {
super.setUp();
//核心方法getActivity()
mActivity = this.getActivity();
//初始化控件
mEditText01 =(EditText) mActivity.findViewById(com.waitingfy.android.R.id.edit01);
mEditText02 =(EditText) mActivity.findViewById(com.waitingfy.android.R.id.edit02);
mButton = (Button)mActivity.findViewById(com.waitingfy.android.R.id.btnSum);
mView = (TextView)mActivity.findViewById(com.waitingfy.android.R.id.txtResult);
}
public void testPreconditions() {
assertNotNull(mEditText01);
assertNotNull(mEditText02);
assertNotNull(mButton);
assertNotNull(mView);
}
/*@UiThreadTest这个注明非常重要,曾经尝试使用
* mActivity.runOnUiThread(new Runnable() {
* public void run() {
*
* }
* });
* 一直报NullPointerException
*/
@UiThreadTest
public void testLegalInput() {
mEditText01.setText("2");
mEditText02.setText("3");
//模拟点击按钮
mButton.performClick();
assertEquals("5", mView.getText().toString());
}
@UiThreadTest
public void testIllegalInput() {
mEditText01.setText("t");
mEditText02.setText("s");
//模拟点击按钮
mButton.performClick();
assertEquals("", mView.getText().toString());
}
@UiThreadTest
public void testNullInput() {
//模拟点击按钮
mButton.performClick();
assertEquals("", mView.getText().toString());
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
}
我们这里写了3个测试方法,第一个测试合法的输入值,看下最后TextView中是否等于5,第二个测试方法我们测试输入非法数字,如两个字符,然后点击按钮,第三个测试方法我们测试输入框中无任何输入值,直接点击按钮。
测试结果如下:
我们就可以根据测试结果进行程序修改了,可以知道我们未考虑到非法输入和空值,看来单元测试还是很有用的,:)。
先到这里,下次再见。