Android Marshmallow: Test permissions with Espresso?

前端 未结 13 1318
庸人自扰
庸人自扰 2020-11-29 19:31

The new permissions scheme introduced by Android Marshmallow requires checking for specific permissions at runtime, which implies the need to provide different flows dependi

相关标签:
13条回答
  • 2020-11-29 20:08

    You can achieve this easily by granting permission before starting the test. For example if you are supposed to use camera during the test run, you can grant permission as follows

    @Before
    public void grantPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getInstrumentation().getUiAutomation().executeShellCommand(
                    "pm grant " + getTargetContext().getPackageName()
                            + " android.permission.CAMERA");
        }
    }
    
    0 讨论(0)
  • 2020-11-29 20:13

    Give a try with such static method when your phone is on English locale:

    private static void allowPermissionsIfNeeded() {
        if (Build.VERSION.SDK_INT >= 23) {
            UiDevice device = UiDevice.getInstance(getInstrumentation());
            UiObject allowPermissions = device.findObject(new UiSelector().text("Allow"));
            if (allowPermissions.exists()) {
                try {
                    allowPermissions.click();
                } catch (UiObjectNotFoundException e) {
                    Timber.e(e, "There is no permissions dialog to interact with ");
                }
            }
        }
    }
    

    I found it here

    0 讨论(0)
  • 2020-11-29 20:13

    Thank you @niklas for the solution. In case anyone looking to grant multiple permissions in Java:

     @Rule
    public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.CAMERA);
    
    0 讨论(0)
  • 2020-11-29 20:15

    ESPRESSO UPDATE

    This single line of code grants every permission listed as parameter in the grant method with immediate effect. In other words, the app will be treated like if the permissions were already granted - no more dialogs

    @Rule @JvmField
    val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION)
    

    and gradle

    dependencies {
      ...
      testImplementation "junit:junit:4.12"
      androidTestImplementation "com.android.support.test:runner:1.0.0"
      androidTestImplementation "com.android.support.test.espresso:espresso-core:3.0.0"
      ...
    }
    

    reference: https://www.kotlindevelopment.com/runtime-permissions-espresso-done-right/

    0 讨论(0)
  • 2020-11-29 20:20

    The accepted answer doesn't actually test the permissions dialog; it just bypasses it. So, if the permissions dialog fails for some reason, your test will give a false green. I encourage actually clicking the "give permissions" button to test the whole app behaviour.

    Have a look at this solution:

    public static void allowPermissionsIfNeeded(String permissionNeeded) {
        try { 
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasNeededPermission(permissionNeeded)) {
            sleep(PERMISSIONS_DIALOG_DELAY);
            UiDevice device = UiDevice.getInstance(getInstrumentation());
            UiObject allowPermissions = device.findObject(new UiSelector()
              .clickable(true) 
              .checkable(false) 
              .index(GRANT_BUTTON_INDEX));
            if (allowPermissions.exists()) {
              allowPermissions.click();
            } 
          } 
        } catch (UiObjectNotFoundException e) {
          System.out.println("There is no permissions dialog to interact with");
        } 
      } 
    

    Find the whole class here: https://gist.github.com/rocboronat/65b1187a9fca9eabfebb5121d818a3c4

    By the way, as this answer has been a popular one, we added PermissionGranter to Barista, our tool above Espresso and UiAutomator to make instrumental tests green: https://github.com/SchibstedSpain/Barista check it out, because we will maintain it release by release.

    0 讨论(0)
  • 2020-11-29 20:20

    For allowing the permission, when necessary, I think the easiest way is to use Barista's PermissionGranter.allowPermissionsIfNeeded(Manifest.permission.GET_ACCOUNTS) directly in the test which requires this permission.

    0 讨论(0)
提交回复
热议问题