How do I grant permission in Espresso?
Asked Answered
M

2

5

I'm trying to grant permission in my Android app during the Espresso test. In my espresso test I have this rule to try and grant permission:

    @Rule
    public final GrantPermissionRule mGrantPermissionRule =
            grant(READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE);

However I get this error:

2020-09-11 07:25:57.825 25911-25943/com.augustinus.fcmtest E/GrantPermissionCallable: Permission: android.permission.READ_EXTERNAL_STORAGE cannot be granted!
2020-09-11 07:25:57.836 25911-25943/com.augustinus.fcmtest E/TestRunner: junit.framework.AssertionFailedError: Failed to grant permissions, see logcat for details
        at junit.framework.Assert.fail(Assert.java:50)
        at androidx.test.runner.permission.PermissionRequester.requestPermissions(PermissionRequester.java:111)
        at androidx.test.rule.GrantPermissionRule$RequestPermissionStatement.evaluate(GrantPermissionRule.java:133)
        at org.junit.rules.RunRules.evaluate(RunRules.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
        at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
        at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
        at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2160)

Is there a different method I should use? I'm using the latest version of Android.

Myopic answered 10/9, 2020 at 21:33 Comment(1)
What does grant() do? Also be sure to use the full identifier for the permissions, e.g. android.Manifest.permission.<PERMISSION>.Shipwreck
M
9

I ended up doing something like this:

    @Rule
    public GrantPermissionRule permissionCamera = GrantPermissionRule.grant(Manifest.permission.CAMERA);
    @Rule
    public GrantPermissionRule permissionAudio = GrantPermissionRule.grant(Manifest.permission.RECORD_AUDIO);
    @Rule
    public GrantPermissionRule permissionLocation = GrantPermissionRule.grant(Manifest.permission.ACCESS_FINE_LOCATION);
    @Rule
    public GrantPermissionRule permissionRead = GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE);
    @Rule
    public GrantPermissionRule permissionWrite = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE);
Myopic answered 13/9, 2020 at 12:40 Comment(0)
I
0

This is how we've been doing it:

@JvmField
@Rule
val permissionRule: GrantPermissionRule = grant(
    Manifest.permission.CAMERA,
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.RECORD_AUDIO,
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.WRITE_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_COARSE_LOCATION
)

Though there was an issue updating to API 33 and using a permission that didn't exist in API 32 and below, so now we have this:

private val permissions = arrayOf(Manifest.permission.CAMERA,
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.RECORD_AUDIO,
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.WRITE_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_COARSE_LOCATION)

@JvmField
@Rule
val permissionRule: GrantPermissionRule =
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        grant(*permissions, Manifest.permission.POST_NOTIFICATIONS)
    } else {
        grant(*permissions)
    }

This is kotlin code so what works for you may be slightly different.

Indiscriminate answered 20/10, 2023 at 14:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.