Issue
EDIT: I've tested the below on two devices on Android API 22 and one on API 19, the one on API 19 does not have the issue. Any ideas what the difference could be between versions?
I am setting up espresso tests for my Android with an IdlingResource identical to the example here.
My Test setup:
@Rule
public ActivityTestRule<MainActivity> mMainActivity =
new ActivityTestRule(MainActivity.class);
private IdlingResource mIdlingResource;
@Before
public void registerIdlingResource() {
mIdlingResource = mMainActivity.getActivity().getIdlingResource();
IdlingRegistry.getInstance().register(mIdlingResource);
}
In my Activity each time I change the Idle state I call:
if (mIdlingResource != null) {
mIdlingResource.setIdleState(false);
} else {
Log.d("error ", "idle resource is null");
}
My issue comes when trying to change the idle state in my activity -- there seems to be a lag between when the activity is created and the IdlingResource is available.
In the first test of the sequence, the IdlingResource is never available -- as such I cannot set the initialValue of the IdlingResource to false and then later switch back to true. That seems to be caused by the annotation lifecycle as described in this article:
From what I can tell the Activity is created by the @Rule and then the IdlingResource is instantiated in the @Before. Since the Activity is already running the idle resource is null at each of the points where I attempt to change the state.
In subsequent tests only the first instance of setIdleState (which occurs in the onCreate) is skipped -- perhaps something to do with the Activity lifecycle with the @Rule? -- but the others operate as expected.
Is there a best practice to getting the @Rule and @Before to work in order before the first test?
Solution
The best solution to this issue of the activity launching before the IdlingResource is available is to set the Rule so that it does not launch the activity. The benefit of this method is that you do not have to manually register the IdlingResource in the Activity.
To make implement this solution, use the following constructor of ActivityTestRule
ActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity)
So the code would look like:
@Rule
public ActivityTestRule<MainActivity> mMainActivity =
new ActivityTestRule(MainActivity.class, false, true);
private IdlingResource mIdlingResource;
@Before
public void registerIdlingResource() {
mIdlingResource = mMainActivity.getActivity().getIdlingResource();
IdlingRegistry.getInstance().register(mIdlingResource);
mMainActivity.launchActivity(new Intent());
}
Answered By - grrrrrr
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.