mfe*_*old 21 android unit-testing
在活动单元测试中,我如何模拟活动生命周期事件.
我可以在现有活动上调用instrumentation的callActivityOn ...方法,但是如何触发活动重新创建,以便活动的OnCreate获取具有已保存状态的bundle
我发现此代码会导致创建新的Activity:
myActivity.finish();
setActivity(null);
myActivity = getActivity();
Run Code Online (Sandbox Code Playgroud)
但这不会导致调用onSaveInstanceState.因此,例如,为了测试在查看方向更改后是否正确创建了活动,此类测试应该执行此操作:
private mInstrumentation = getInstrumentation();
...
final Bundle outState = new Bundle();
mInstrumentation.callActivityOnSaveInstanceState(mActivity, outState);
mActivity.finish();
setActivity(null);
mActivity = getActivity();
runTestOnUiThread(new Thread() {
@Override
public void run() {
mInstrumentation.callActivityOnRestoreInstanceState(mActivity, outState);
}
});
Run Code Online (Sandbox Code Playgroud)
不要按照状态管理测试示例:{dead link}
myActivity.finish();
myActivity = getActivity();
Run Code Online (Sandbox Code Playgroud)
ActivityInstrumentationTestCase2.getActivity()在第一次调用Activity时启动Activity,但它只是在测试用例的每个后续调用中返回相同的Activity.因此,您仍然在查看已完成的活动.
完成第一个Activity后,您需要从测试中开始一个新的Activity.InstrumentationTestCase.launchActivity()例如,您可以使用.
作为另一个例子,我编写了一个测试,在ActivityA中按下一个按钮,启动ActivityB for-result; 测试然后立即杀死ActivityA(通过方向更改,但finish()也可以工作),然后测试获取系统在ActivityB完成时创建并发送其结果的新ActivityA的句柄.诀窍是让测试添加一个Instrumentation.ActivityMonitor,然后让该监视器等待系统启动新的ActivityA并为测试提供一个句柄.
编辑2/23/2012 cdhabecker,添加可重现的代码:
public class VerboseActivity extends Activity {
public final static String TAG = "Verbose";
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate() " + (Activity)this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity5);
}
@Override
protected void onDestroy() {
Log.i(TAG, "onDestroy().");
super.onDestroy();
}
}
Run Code Online (Sandbox Code Playgroud)
测试用例:( sleep()调用为活动提供了大量响应时间)
public class VerboseTest extends
ActivityInstrumentationTestCase2<VerboseActivity> {
Activity myActivity = null;
public VerboseTest() {
super("com.scanillion.demo", VerboseActivity.class);
}
public void test_01() {
String TAG = "test_01";
myActivity = getActivity();
Log.i(TAG, "A getActivity()=" + myActivity);
myActivity.finish();
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
}
myActivity = getActivity();
Log.i(TAG, "B getActivity()=" + myActivity);
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
日志:
02-23 21:25:37.689: I/Verbose(17747): onCreate() com.scanillion.demo.VerboseActivity@43ba3360
02-23 21:25:38.159: I/ActivityManager(67): Displayed activity com.scanillion.demo/.VerboseActivity: 526 ms (total 526 ms)
02-23 21:25:38.180: I/test_01(17747): A getActivity()=com.scanillion.demo.VerboseActivity@43ba3360
02-23 21:25:38.540: I/Verbose(17747): onDestroy().
02-23 21:25:43.236: I/test_01(17747): B getActivity()=com.scanillion.demo.VerboseActivity@43ba3360
02-23 21:25:48.439: I/TestRunner(17747): finished: test_01(com.scanillion.demo.test.VerboseTest)
02-23 21:25:48.439: I/TestRunner(17747): passed: test_01(com.scanillion.demo.test.VerboseTest)
Run Code Online (Sandbox Code Playgroud)
注意finish()引起的onDestroy(),但随后getActivity()是无操作.getActivity()不仅不实例化新的Activity,甚至不会重新创建原始的Activity.
如果您使用的是 Android 4.x 设备,则可以进入“设置”>“开发者选项”并选中“不保留活动”。现在,每当您的 Activity 失去焦点(例如:HOME 按钮)时,它将被终止并调用 onSaveInstanceState(...) 。
当您恢复应用程序时,如果您将 Activity 保存在 onSaveInstanceState(...) 中,则 Activity 应该在 onCreate(...) 方法中包含捆绑数据。