Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Instrumentation Launch Activity

I have a simple activity that contains a button. When i press the button a second activity runs. Now I am new to Android Instrumentation Testing. So far this is what I have written

public class TestSplashActivity extends
    ActivityInstrumentationTestCase2<ActivitySplashScreen> {

private Button mLeftButton;
private ActivitySplashScreen activitySplashScreen;
private ActivityMonitor childMonitor = null;
public TestSplashActivity() {
    super(ActivitySplashScreen.class);
}

@Override
protected void setUp() throws Exception {
    super.setUp();
    final ActivitySplashScreen a = getActivity();
    assertNotNull(a);
    activitySplashScreen=a;
    mLeftButton=(Button) a.findViewById(R.id.btn1);

}

@SmallTest
public void testNameOfButton(){
    assertEquals("Press Me", mLeftButton.getText().toString());
    this.childMonitor = new ActivityMonitor(SecondActivity.class.getName(), null, true);
    this.getInstrumentation().addMonitor(childMonitor);
    activitySplashScreen.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            mLeftButton.performClick();
    }});

    Activity childActivity=this.getInstrumentation().waitForMonitorWithTimeout(childMonitor, 5000);
    assertEquals(childActivity, SecondActivity.class);

}

}

Now the first assert where I get the text of the button works. But when I call the perform click, I get an exception

  Only the original thread that created a view hierarchy can touch its views. 

Now I understand this exception in the context of Android applications, but now in the terms of instrumentation testing. How can I perform the click event on the button, and how can I check whether my second activity has been loaded.

like image 319
user1730789 Avatar asked Oct 04 '22 16:10

user1730789


1 Answers

Assuming you have a test class which extends InstrumentationTestCase, and that you are in a test method, it should follow this logic:

  1. Register your interest in the activity you want to check.
  2. Launch it
  3. Do what you want with it. Check if components are right, perform user actions, and that kind of thing.
  4. Register your interest for the next activity in the "sequence"
  5. Perform the action of that activity which makes the next activity of the sequence pop up.
  6. Repeat, following this logic...

In terms of code, this would result in something like the following:

Instrumentation mInstrumentation = getInstrumentation();
// We register our interest in the activity
Instrumentation.ActivityMonitor monitor = mInstrumentation.addMonitor(YourClass.class.getName(), null, false);
// We launch it
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClassName(mInstrumentation.getTargetContext(), YourClass.class.getName());
mInstrumentation.startActivitySync(intent);

Activity currentActivity = getInstrumentation().waitForMonitor(monitor);
assertNotNull(currentActivity);
// We register our interest in the next activity from the sequence in this use case
mInstrumentation.removeMonitor(monitor);
monitor = mInstrumentation.addMonitor(YourNextClass.class.getName(), null, false);

To send clicks, do something like the following:

View v = currentActivity.findViewById(....R.id...);
assertNotNull(v);
TouchUtils.clickView(this, v);
mInstrumentation.sendStringSync("Some text to send into that view, if it would be a text view for example. If it would be a button it would already have been clicked by now.");
like image 176
Luis Miguel Serrano Avatar answered Oct 10 '22 02:10

Luis Miguel Serrano