Android – UiAutomator picking app to test from app drawer

androidandroid-uiautomatortesting

I'm trying to write an UI automated 'black box' test for an android application (I have the apk but not the source code) using UiAutomator.
I'm having trouble opening the app for the drawer during the set-up phase. So far my code is

@Override
public void setUp() throws Exception {
    super.setUp();
    mDevice = UiDevice.getInstance(getInstrumentation());
    mDevice.pressHome();
    //Wait for the app drawer icon to show up on the screen
    mDevice.wait(Until.hasObject(By.desc("Apps")), 3000);
    //Obtain reference to the app drawer button in order to click it
    UiObject drawerIcon = mDevice.findObject(new UiSelector().description("Apps"));
    drawerIcon.clickAndWaitForNewWindow();
    //Finding and Clicking on the Sunshine app
    UiObject drawer = mDevice.findObject(new UiSelector().resourceId("com.sec.android.app.launcher:id/apps_grid"));
    UiObject appToTest = mDevice.findObject(new UiSelector().description("app-to-test-description"));
    while (!appToTest.exists()) {
        drawer.swipeLeft(3);
    }
    appToTest.clickAndWaitForNewWindow();
}

When I run the test it should open the app (then run the varius testing methods that I have yet to write.)
Instead it opens the drawer and it hangs. I guess there is a better way to identify the drawer and scroll it until the right application is found.
Here is the error log.

Running tests
Test running started
android.support.test.uiautomator.UiObjectNotFoundException: UiSelector[RESOURCE_ID=com.sec.android.app.launcher:id/apps_grid]
at android.support.test.uiautomator.UiObject.getVisibleBounds(UiObject.java:891)
at android.support.test.uiautomator.UiObject.swipeLeft(UiObject.java:315)
at com.crisanti.roberto.uturistautomatedtest.UiAutomatorTest.setUp(UiAutomatorTest.java:29)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)

Best Answer

If you really want to start it from the menu you already answered your own question. However bear in mind that in different devices the apps drawer may be different (Samsung and others usually do their own on top of Android's).

As an alternative you can

Context context = InstrumentationRegistry.getInstrumentation().getContext(); //gets the context based on the instrumentation
Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageNameOfYourApp);  //sets the intent to start your app
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);  //clear out any previous task, i.e., make sure it starts on the initial screen
context.startActivity(intent);  //starts the app

The package name you can have by using UiAutomatorViewer (in sdk-folder/tools/).

If you want you can wait until the app is actually started by doing this (I assume you already have a UiDevice device).

device.wait(Until.hasObject(By.pkg(packageNameOfYourApp)), timeOut); //ofc you need to set timeout

This will work for any device/emulator configuration.

Related Topic