Android revoke permission at start of each test

I'm using Espresso and UIAutomator to write my test cases. I'm testing external storage permissions when it's denied and when it's allowed. I have different test cases which all require the permission to be revoked at the start of the test case. However, some of the test cases should and do result in the permission being granted, so I need to revoke the permission when the next test is being executed. I have searched around and the closest thing I came across is using the pm manager to execute adb shell commands to revoke the permission. However by doing so, I'll get the following error, Instrumentation run failed due to 'process crash'. Is there any way I can ensure permissions are revoked at the beginning of every test case? If not, how can this issue be resolved regarding testing permissions? Thank you for your help in advance!

This is the code snippet I currently have to revoke permission before each test case (which doesn't work):

@Before
public void setUp() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        getInstrumentation().getUiAutomation().executeShellCommand(
                "pm revoke " + getTargetContext().getPackageName()
                        + " android.permission.WRITE_EXTERNAL_STORAGE");
    }
}

Corresponding error message when trying to revoke permission with above code snippet:

Test failed to run to completion. Reason: 'Instrumentation run failed due to 'Process crashed.''.

I have also come across these two posts: this and this.


I'm not sure on how to do that at runtime without prompting the user. However, you stated in the title that it is for test purposes. Therefore I have some options i can suggest you

a)When testing need be done without permissions, just revoke it manually using the settings of your device.

b) You could check and ask for permission, then refuse to give permission. I'd give you some code I use to check and ask for camera permission. You'd just have to change the permission name, and maybe the condition to check :

public static boolean checkCameraPermission(MainActivity thisActivity) {
    return ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_GRANTED;
}

public static void checkAndAskCameraPermission(final MainActivity thisActivity) {

    if (!checkCameraPermission(thisActivity)) {
        //No right is granted
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.CAMERA)) {

            //Open a dialog explaining why you are asking permission then when when positive button is triggered, call this line
            ActivityCompat.requestPermissions(thisActivity,
                            new String[]{Manifest.permission.CAMERA},
                            CHECK_FOR_CAMERA_PERMISSION);

        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.CAMERA},
                    CHECK_FOR_CAMERA_PERMISSION);
        }
    }
}

I could give you some more links about the b) (how to ask permissions) if you need so (just comment it). However as i'm not sure this answer would interest you, i won't spend time to document this option.

But then, maybe someone will be able to explain you how to do it directly at runtime without prompting, but I though it may be interesting to provide you at least this information.


You can't. Grant/Revoke permissions is under user control.

However, you can grant/revoke permissions via adb and you can trigger adb commands programmatically, but I have no idea if this works in combination?...

adb shell pm grant [app.package] [permission]
adb shell pm grant com.app.package.path android.permission.READ_CONTACTS

(look here)

You might map your permissions to boolean value for testing purposes?


I've implemented a solution which leverages wrapper classes, overriding and build variant configuration. The solution is quite long to explain and is found over here: https://github.com/ahasbini/AndroidTestMockPermissionUtils.

It is not yet packed in an sdk but the main idea is to override the functionalities of ContextWrapper.checkSelfPermission and ActivityCompat.requestPermissions to be manipulated and return mocked results tricking the app into the different scenarios to be tested like: permission was denied hence the app requested it and ended with granted permission. This scenario will occur even if the app had the permission all along but the idea is that it was tricked by the mocked results from the overriding implementation.

Furthermore the implementation has a TestRule called PermissionRule class which can be used in the test classes to easily simulate all of the conditions to test the permissions seamlessly. Also assertions can be made like ensuring the app has called requestPermissions() for example.

链接地址: http://www.djcxy.com/p/96028.html

上一篇: 无法绑定到服务器:需要强(呃)身份验证

下一篇: Android每次测试开始时都会撤销权限