簡體   English   中英

Android的儀器測試 - 如何在方向更改后接收新的活動?

[英]Instrumentation test for Android - How to receive new Activity after orientation change?


我正在嘗試測試,如果新創建的Activity(在方向更改后)正確地重新初始化。 下面的代碼顯示從getActivity()返回的活動是在setUp()中構造的活動,而不是新創建的活動。

測試:

public class MyActivityTest extends ActivityInstrumentationTestCase2<MyActivity>{
 private static final String TAG = "RAMPS";
 private MyActivity mActivity;

 public MyActivityTest() {
    super("com.ramps", MyActivity.class);       
 }

 protected void setUp() throws Exception {
     super.setUp();
     mActivity = getActivity();
     Log.v(TAG, "setUp; activity=" + mActivity);
 }

public void testOrienationChange(){
     mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
     getInstrumentation().waitForIdleSync();
     MyActivity newActivity = getActivity(); //should be new, but it's not
     Log.v(TAG, "testOrienationChange; activity=" + newActivity);       
 }
}


Activiy:

public class MyActivity extends Activity {
    private static final String TAG = "RAMPS";  

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(TAG, "onCreate; activity=" + this);
    setContentView(new TextView(this));     
 }
    //...rest of stuff like onSaveInstanceState() etc.
}


和日志:

06-11 14:16:52.431: V/RAMPS(367): onCreate; activity=MyActivity@44eb8690
06-11 14:16:52.891: V/RAMPS(367): setUp; activity=MyActivity@44eb8690
06-11 14:16:52.971: V/RAMPS(367): onCreate; activity=MyActivity@44ee5178
06-11 14:16:53.131: V/RAMPS(367): testOrienationChange; activity=MyActivity@44eb8690


如前所述,日志顯示確實創建了新活動(MyActivity @ 44ee5178),但getActivity()返回在setUp()(MyActivity @ 44eb8690)中創建的舊活動。 是否可以訪問新創建的?

好吧,我想我終於設法解決了它 - 使用robotium框架。 我正在附加解決方案以防有人遇到同樣的問題。

測試:

public class MyActivityTest extends ActivityInstrumentationTestCase2<MyActivity>{

private static final String TAG = "RAMPS";
private MyActivity mActivity;
private Solo mSolo;

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

}

@Override
protected void setUp() throws Exception {
    super.setUp();
    mActivity = getActivity();
    mSolo = new Solo(getInstrumentation(), getActivity());
    Log.v(TAG, "setUp; activity=" + mActivity);
}

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

}

並記錄消息 - 用於確認:

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

如您所見,從mSolo.getCurrentActivity()返回的活動與在方向更改后創建的活動相同。 我真的推薦Robotium - 來自Jayway的另一個很棒的代碼!

我的UI測試中遇到了同樣的問題。 我不使用Robotium,但是我使用getActivity()創建了一個新的基礎測試類,它始終返回當前活動。 我們的想法是在方向更改之前添加一個ActivityMonitor ,並在監視器等待時更新當前活動:

public class UiTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {

private final Class<T> activityClass;
protected T activity;

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

@Override
protected void setUp() 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.
 */
protected final void rotate() {
  int nextOrientation =
      activity.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
          ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
          : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
  Instrumentation.ActivityMonitor monitor =
      new Instrumentation.ActivityMonitor(activityClass.getName(), null, false);
  getInstrumentation().addMonitor(monitor);
  activity.setRequestedOrientation(nextOrientation);
  getInstrumentation().waitForIdleSync();
  this.activity = (T) getInstrumentation().waitForMonitor(monitor);
}

@Override
public T getActivity() {
  return activity;
}

當然,如果活動類在測試期間發生變化,或者方向通過其他方式而不是使用rotate()方法更改,則此方法無效。 我希望這有助於某人。

代替

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

嘗試

MyActivity newActivity = instrumentation.startActivitySync(intent);

我認為這種方法可能對你有幫助

取了@Smok的答案並將其更新為始終旋轉:

@SuppressWarnings("unchecked") // it's fine
public static <T extends Activity> T rotate(ActivityInstrumentationTestCase2<T> testCase) {
    T activity = testCase.getActivity();
    int orientation = activity.getWindowManager().getDefaultDisplay().getRotation();
    int nextOrientation = orientation == Configuration.ORIENTATION_LANDSCAPE ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(activity.getClass().getName(), null, false);
    testCase.getInstrumentation().addMonitor(monitor);
    activity.setRequestedOrientation(nextOrientation);
    testCase.getInstrumentation().waitForIdleSync();
    return (T) testCase.getInstrumentation().waitForMonitor(monitor);
}

這解決了返回UNSPECIFIED的方向問題

這解決了我的問題,僅使用Android測試框架:

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

AFAIK, getActivity()確實創建了一個新活動,如果當前的活動為null,則通過使用setActivity(null)設置它。 此外,新活動將具有Activity.setRequestedOrientation(int)設置的方向。

如果需要檢查方向更改時是否正確保存狀態,則應從UI線程調用getInstrumentation().callActivityOnCreate(mActivity, Bundle)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM