Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destroy and restart Activity with Testing Support Library

Using the old JUnit3-style tests in Android, I could do the following to destory and restart an activity:

Instrumentation inst = getInstrumentation();
Activity activity = inst.getActivity();
// do something
activity.finish();
Assert.assertTrue(this.activity.isFinishing());
activity = inst.getActivity();
// assert that activity's state is restored

How can I accomplish the same thing using the new Testing Support Library? I'm fine with using either Espresso and/or UI Automator or any other mechanism provided by the new library.

Update:

I tried the following:

Activity activity = activityTestRule.getActivity();
// do something
activity.finish();
Assert.assertTrue(this.activity.isFinishing());
activity = activityTestRule.getActivity();
// assert that activity's state is restored

However, it appears that ActivityTestRule.getActivity() does not restart the activity.

like image 573
Code-Apprentice Avatar asked Feb 10 '16 03:02

Code-Apprentice


People also ask

What is ActivityScenarioRule?

ActivityScenarioRule launches a given activity before the test starts and closes after the test. You can access the ActivityScenario instance via getScenario() . You may finish your activity manually in your test, it will not cause any problems and this rule does nothing after the test in such cases.

What is AndroidX test?

AndroidX Test is a collection of Jetpack libraries that lets you run tests against Android apps. It also provides a series of tools to help you write these tests. For example, AndroidX Test provides JUnit4 rules to start activities and interact with them in JUnit4 tests.

What function should be call to shut down an activity?

You can shut down an activity by calling its finish() method. You can also shut down a separate activity that you previously started by calling finishActivity() .

How do you recreate current activity?

For recreating the activity, you can use the simple recreate() or startActivity(intent). or can use to reopen the activty by startActivity.


1 Answers

As @CommonsWare mentioned, a custom rule is pretty useful. Here's my simple solution (many improvements are possible, but this is just a quick framework that can be built on):

public class ControlledActivityTestRule<T extends Activity> extends ActivityTestRule<T> {
    public ControlledActivityTestRule(Class<T> activityClass) {
        super(activityClass, false);
    }

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode) {
        super(activityClass, initialTouchMode, true);
    }

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) {
        super(activityClass, initialTouchMode, launchActivity);
    }

    public void finish() {
        finishActivity();
    }

    public void relaunchActivity() {
        finishActivity();
        launchActivity();
    }

    public void launchActivity() {
        launchActivity(getActivityIntent());
    }
}

Note, if you do it like this, this class needs to be in the package android.support.test.rule to access the package private method ActivityTestRule#finishActivity. Then in your test case, implement this rule:

@Rule
public ControlledActivityTestRule<TestFountainPreferenceActivity> actRule = new ControlledActivityTestRule<>(TestFountainPreferenceActivity.class);

Then in your individual test case, call actRule.finish() and actRule.launchActivity() to kill and restart it. Or you can call actRule.relaunchActivity() if you don't need to do anything in between killing it and starting it up again. Note, you can pass the third parameter false to delay starting the activity if you have initial startup, and then call actRule.launchActivity() to get it going, but you will loose access to some of the built in handles such as #afterActivityLaunched and #afterActivityFinished().

like image 129
JCricket Avatar answered Oct 21 '22 16:10

JCricket