结合Robotium和Monitor类来监控活动的创建
新Activity的创建及监控涉及到多个Activity的集成测试,通常使用ActivityInstrumentationTestCase2< Class >来测试时需要用一个具体的Activity类来实现这个泛型,而一旦这样做以后,在整个该测试用例内无论任何时候调用getActivity()方法所获得的Activity永远都是刚开始用来实例化泛型的那个Activity,假如这时候页面上实际操作的Activity已经是一个新打开的Activity,这时想要操作新Activity上面的组件将比较困难。当然这时候使用Robotium将能很好地解决这个问题。
以下展示如何在测试项目中监控新Activity的创建。
待测项目中包含3个Activity:MainActivity、LinkActivity以及一个OtherActivity。在MainActivity上有两个按钮,分别用来实现打开另外两个Activity:
测试项目中将监控是否成功的创建了新的Activity。
MainActivity的主要代码如下:
public class MainActivity extends Activity {
Button btn1 ;
Button btn2 ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button)findViewById(R.id.button1);
btn2 = (Button)findViewById(R.id.button2);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, LinkActivity.class);
startActivity(intent);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, OtherActivity.class);
startActivity(intent);
}
});
}
测试用例的代码如下:
package com.winstonwolfe.simpledemo.test;
import com.winstonwolfe.simpledemo.R; //因为需要引用到待测项目的资源,所以需要导入待测项目的R类
import com.winstonwolfe.simpledemo.*;
import com.jayway.android.robotium.solo.Solo;
import android.app.Activity;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.content.Intent;
import android.content.IntentFilter;
import android.app.Instrumentation.ActivityMonitor;
import android.view.View;
import android.util.Log;
//和使用Instrumentation测试框架一样,测试用例的基类也是ActivityInstrumentationTestCase2,但是注意这里没有实现泛型类型
@SuppressWarnings("rawtypes")
public class TestMonitor extends ActivityInstrumentationTestCase2 {
private static String PACKAGE = "com.winstonwolfe.simpledemo";
private static String FIRST_ACTIVITY = "com.winstonwolfe.simpledemo.MainActivity"; //待测应用的入口Activity
private static String OTHER_ACTIVITY = "com.winstonwolfe.simpledemo.OtherActivity";
private static String LINK_ACTIVITY = "com.winstonwolfe.simpledemo.LinkActivity";
private Solo _solo; //Robotium的API主对象
@SuppressWarnings({ "unchecked", "deprecation" })
public TestMonitor() throws ClassNotFoundException {
super( Class.forName(LINK_ACTIVITY));
}
public void setUp() throws Exception{
_solo = new Solo(getInstrumentation(), getActivity());
}
public void tearDown() throws Exception{
_solo.finishOpenedActivities();
}
public void testNewOtherActivity(){
_solo.assertCurrentActivity("当前是在MainActivity上执行测试",MainActivity.class );
Instrumentation inst = getInstrumentation();
if(inst == null)
Log.v("错误","Instrumentationinst为null");
ActivityMonitor monitorNewOtherActivity = new ActivityMonitor(OTHER_ACTIVITY,null,false);//初始化监控"新建OtherActivity"的行为
inst.addMonitor(monitorNewOtherActivity);
View btn_other = this.getActivity().findViewById(R.id.button2);
Activity activity = monitorNewOtherActivity.waitForActivity();
_solo.clickOnView(btn_other);
assertEquals(true,activity.toString().indexOf("OtherActivity")>-1); //断言OtherActivity被新建
inst.removeMonitor(monitorNewOtherActivity);
_solo.goBack();//返回到MainActivity
}
public void testNewLinkActivity(){
_solo.assertCurrentActivity("当前是在MainActivity上执行测试",MainActivity.class );
Instrumentation inst = getInstrumentation();
ActivityMonitor monitorLinkActivity = new ActivityMonitor(LINK_ACTIVITY,null,false);
inst.addMonitor(monitorLinkActivity);
View btn_link = this.getActivity().findViewById(R.id.button1);
_solo.clickOnView(btn_link);
Activity activity = monitorLinkActivity.waitForActivity();
assertEquals(true,activity.toString().indexOf(".LinkActivity")>-1); //断言LinkActivity被新建
inst.removeMonitor(monitorLinkActivity);
_solo.goBack();//返回到MainActivity
}
}
附:
ActivityMonitor的两个构造函数:
public Instrumentation.ActivityMonitor (IntentFilter which, Instrumentation.ActivityResult result,boolean block)
引入自:API 级别1
Create a newActivityMonitor that looksfor aparticular kind of intent to be started.
参数
which | The set of intents this monitor is responsible for. |
result | A canned result to return if the monitor is hit; can be null. |
block | Controls whether the monitor should block the activity start (returning its canned result) or let the call proceed. |
参见
· addMonitor(Instrumentation.ActivityMonitor)
public Instrumentation.ActivityMonitor (String cls, Instrumentation.ActivityResult result,boolean block)
引入自:API 级别1
Create a newActivityMonitor that looksfor aspecific activity class to be started.
参数
cls | The activity class this monitor is responsible for. |
result | A canned result to return if the monitor is hit; can be null. |
block | Controls whether the monitor should block the activity start (returning its canned result) or let the call proceed. |
参见
· addMonitor(Instrumentation.ActivityMonitor)
参考文献:
http://blog.csdn.net/sfshine/article/details/7522067