5


我正在尝试测试新创建的活动(在方向更改后)是否正确重新初始化。下面的代码显示从 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);       
 }
}


活动:

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)。是否可以访问新创建的?

4

5 回答 5

5

好的,我想我终于设法解决了 - 使用机器人框架。我附上解决方案,以防有人遇到同样的问题。

测试:

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 的另一个很棒的代码!

于 2012-06-11T19:04:31.597 回答
4

我在 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()方法发生变化,这将不起作用。我希望这对某人有所帮助。

于 2013-12-13T15:50:38.510 回答
1

代替

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

尝试

MyActivity newActivity = instrumentation.startActivitySync(intent);

我认为这种方法可能对您有所帮助

于 2013-09-07T11:17:45.867 回答
0

接受@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

于 2014-03-25T11:57:10.073 回答
0

这解决了我的问题,仅使用 Android 测试框架:

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

AFAIK,getActivity()如果当前活动为空,则确实会创建一个新活动,这是通过将其设置为setActivity(null). 此外,新活动的方向由 设置Activity.setRequestedOrientation(int)

如果您需要在方向更改时检查状态是否正确保存,您应该getInstrumentation().callActivityOnCreate(mActivity, Bundle)从 UI 线程调用。

于 2015-02-11T12:20:25.230 回答