Android UiAutomator从应用程序抽屉中选择要测试的应用程序

Android UiAutomator从应用程序抽屉中选择要测试的应用程序,android,testing,android-uiautomator,Android,Testing,Android Uiautomator,我正在尝试使用UiAutomator为android应用程序(我有apk,但没有源代码)编写一个UI自动“黑盒”测试。 在设置阶段,我无法打开抽屉的应用程序。到目前为止,我的代码是 @Override public void setUp() throws Exception { super.setUp(); mDevice = UiDevice.getInstance(getInstrumentation()); mDevice.pressHome(); //Wa

我正在尝试使用UiAutomator为android应用程序(我有apk,但没有源代码)编写一个UI自动“黑盒”测试。 在设置阶段,我无法打开抽屉的应用程序。到目前为止,我的代码是

@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();
}
当我运行测试时,它应该打开应用程序(然后运行我尚未编写的varius测试方法) 相反,它打开抽屉,挂了起来。我想有更好的方法来识别抽屉并滚动它直到找到正确的应用程序。 这是错误日志

运行测试
已开始测试运行
android.support.test.uiautomator.UiObjectNotFoundException:UiSelector[RESOURCE\u ID=com.sec.android.app.launcher:ID/apps\u grid] 位于android.support.test.uiautomator.UiObject.getVisibleBounds(UiObject.java:891) 位于android.support.test.uiautomator.UiObject.swipeLeft(UiObject.java:315) 在com.crisanti.roberto.uturistautomatedtest.UiAutomatorTest.setUp(UiAutomatorTest.java:29) 位于android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191) 位于android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176) 位于android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555) 位于android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)


我已经想好了如何让它工作。在棒棒糖上,启动器由
“com.google.android.googlequicksearchbox:id/apps\u customize\u pane\u content”
标识,而不是由
“com.sec.android.app.launcher:id/apps\u grid”
标识。这可能是一个问题,因为测试取决于平台版本(在Kitkat上,发射器有另一个行为,在Marshmellow上,发射器也有另一个不同的行为)。 我做的另一个修改正在进行中 抽屉。左开关(3); 我换成了 抽屉。开关柜(5)

使用棒棒糖上的UiAutomator启动应用程序的代码总结如下:

public void setUp() throws Exception {
        super.setUp();
        mDevice = UiDevice.getInstance(getInstrumentation());
        mDevice.pressHome();
        //Obtain reference to the app drawer button in order to click it
        UiObject allAppsButton = mDevice.findObject(new UiSelector().description("Apps"));
        //The operation below expects the click will result a new  window.
        allAppsButton.clickAndWaitForNewWindow();
        // Find the application in the app launcher
        UiObject appViews = mDevice.findObject(new UiSelector().resourceId("com.google.android.googlequicksearchbox:id/apps_customize_pane_content"));
        UiObject navigationDrawerApp = mDevice.findObject(new UiSelector().text("app-to-test-name"));
        while (!navigationDrawerApp.exists()){
            appViews.swipeLeft(5);
        }
        navigationDrawerApp.clickAndWaitForNewWindow();
}

如果你真的想从菜单开始,你已经回答了你自己的问题。不过,请记住,在不同的设备上,应用程序抽屉可能会有所不同(三星和其他公司通常在安卓系统的基础上自行开发)

作为替代,你可以

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
使用UiAutomatorViewer(在sdk文件夹/tools/中)可以拥有的包名称

如果您愿意,您可以等待应用程序实际启动(我假设您已经有了UiDevice)


这适用于任何设备/仿真器配置。

感谢您提及此专业提示:“使用UiAutomatorViewer(sdk文件夹/tools/)可以获得的包名。”我们的应用程序包名末尾有一个“.debug”,但我使用的是原始包名(没有后缀),因此返回的意图始终为空。这个“.debug”后缀可能来自构建类型。不管怎样都让我发疯了!
device.wait(Until.hasObject(By.pkg(packageNameOfYourApp)), timeOut); //ofc you need to set timeout