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.
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.
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.
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() .
For recreating the activity, you can use the simple recreate() or startActivity(intent). or can use to reopen the activty by startActivity.
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()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With