Skip to content Skip to sidebar Skip to footer

Instrumentation Test For Android - How To Receive New Activity After Orientation Change?

I'm trying to test, if newly created Activity (after orientation change) is properly reinitialized. The code below shows that activity returned from getActivity() is the one const

Solution 1:

Ok, I think I finally managed to solve it - with robotium framework. I'm attaching the solution in case someone had the same problem.

Test:

publicclassMyActivityTestextendsActivityInstrumentationTestCase2<MyActivity>{

privatestaticfinalStringTAG="RAMPS";
private MyActivity mActivity;
private Solo mSolo;

publicMyActivityTest() {
    super("com.ramps", MyActivity.class);

}

@OverrideprotectedvoidsetUp()throws Exception {
    super.setUp();
    mActivity = getActivity();
    mSolo = newSolo(getInstrumentation(), getActivity());
    Log.v(TAG, "setUp; activity=" + mActivity);
}

publicvoidtestOrienationChange(){     
    mSolo.setActivityOrientation(Solo.LANDSCAPE);
    getInstrumentation().waitForIdleSync();
    MyActivitynewActivity= getActivity(); //should be new, but it's notActivitynewActivity2= mSolo.getCurrentActivity(); //this will return new activity
    Log.v(TAG, "testOrienationChange; activity=" + newActivity);
    Log.v(TAG, "testOrienationChange; activity2=" + newActivity2);
}   

}

And log messages - for confirmation:

06-1118:47:02.631: V/RAMPS(716): onCreate; activity=MyActivity@44c326a8
06-1118:47:03.061: V/RAMPS(716): setUp; activity=MyActivity@44c326a8
06-1118:47:03.781: V/RAMPS(716): onCreate; activity=MyActivity@44c481e0
06-1118:47:04.482: V/RAMPS(716): testOrienationChange; activity=MyActivity@44c326a8
06-1118:47:04.482: V/RAMPS(716): testOrienationChange; activity2=MyActivity@44c481e0

As you can see, activity returned from mSolo.getCurrentActivity() is the same that was created after orientation change. I really recommend Robotium - another great piece of code from Jayway!

Solution 2:

I've had the same problem in my UI tests. I don't use Robotium, but I created a new base test class with getActivity() that always returns current activity. The idea is to add an ActivityMonitor before orientation change and just update current activity on monitor wait:

publicclassUiTest<T extendsActivity> extendsActivityInstrumentationTestCase2<T> {

privatefinal Class<T> activityClass;
protected T activity;

publicUiTest(Class<T> activityClass) {
  super(activityClass);
  this.activityClass = activityClass;
}

@OverrideprotectedvoidsetUp()throws Exception {
  super.setUp();
  setActivityInitialTouchMode(false);  // Depends on your needs.
  activity = super.getActivity();
  activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

/**
 * Rotates the test device and updates current activity.
 */protectedfinalvoidrotate() {
  intnextOrientation=
      activity.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
          ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
          : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
  Instrumentation.ActivityMonitormonitor=newInstrumentation.ActivityMonitor(activityClass.getName(), null, false);
  getInstrumentation().addMonitor(monitor);
  activity.setRequestedOrientation(nextOrientation);
  getInstrumentation().waitForIdleSync();
  this.activity = (T) getInstrumentation().waitForMonitor(monitor);
}

@Overridepublic T getActivity() {
  return activity;
}

Of course this won't work if activity class changes during the test or if orientation changes by other means, not with rotate() method. I hope this helps somebody.

Solution 3:

Instead of

MyActivitynewActivity= getActivity(); //should be new, but it's not

Try

MyActivitynewActivity= instrumentation.startActivitySync(intent);

I think this method maybe help you

Solution 4:

Took @Smok's answer and updated it to always rotate:

@SuppressWarnings("unchecked")// it's finepublicstatic <T extendsActivity> T rotate(ActivityInstrumentationTestCase2<T> testCase) {
    Tactivity= testCase.getActivity();
    intorientation= activity.getWindowManager().getDefaultDisplay().getRotation();
    intnextOrientation= orientation == Configuration.ORIENTATION_LANDSCAPE ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    Instrumentation.ActivityMonitormonitor=newInstrumentation.ActivityMonitor(activity.getClass().getName(), null, false);
    testCase.getInstrumentation().addMonitor(monitor);
    activity.setRequestedOrientation(nextOrientation);
    testCase.getInstrumentation().waitForIdleSync();
    return (T) testCase.getInstrumentation().waitForMonitor(monitor);
}

This fixes the problem of the orientation returning UNSPECIFIED

Solution 5:

This solved my issue, using only the Android testing framework:

    mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    mActivity.finish();
    setActivity(null);
    mActivity = getActivity();
    getInstrumentation().waitForIdleSync();

AFAIK, getActivity() does create a new activity if the current one is null which is done by setting it with setActivity(null). Also, the new activity will have the orientation set by Activity.setRequestedOrientation(int).

If you need to check whether the state is being correctly saved when orientation changes, you should call getInstrumentation().callActivityOnCreate(mActivity, Bundle) from the UI thread.

Post a Comment for "Instrumentation Test For Android - How To Receive New Activity After Orientation Change?"