活动生命周期单元测试

mfe*_*old 21 android unit-testing

在活动单元测试中,我如何模拟活动生命周期事件.

我可以在现有活动上调用instrumentation的callActivityOn ...方法,但是如何触发活动重新创建,以便活动的OnCreate获取具有已保存状态的bundle

Mic*_*hal 9

我发现此代码会导致创建新的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)


cdh*_*ker 6

不要按照状态管理测试示例:{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.

  • @yorkw我添加了一个可重现的案例. (2认同)

tri*_*iad 1

如果您使用的是 Android 4.x 设备,则可以进入“设置”>“开发者选项”并选中“不保留活动”。现在,每当您的 Activity 失去焦点(例如:HOME 按钮)时,它将被终止并调用 onSaveInstanceState(...) 。

当您恢复应用程序时,如果您将 Activity 保存在 onSaveInstanceState(...) 中,则 Activity 应该在 onCreate(...) 方法中包含捆绑数据。

  • 嗯,这可能适用于手动测试。我正在寻找一种在自动化测试中做到这一点的方法 (3认同)