How to manage Runtime permissions android marshmallow espresso tests

后端 未结 12 943
孤独总比滥情好
孤独总比滥情好 2020-12-05 02:33

I\'m using espresso for testing but sometimes I try to get an image form external storage and with marshmallow I need a Runtime permission otherwise there will be an Excepti

12条回答
  •  北荒
    北荒 (楼主)
    2020-12-05 03:32

    UPDATE! Now you can use Rule from Android Testing Support Library

    It is more proper to use than custom rules.

    Outdated answer:

    You can add test rule to reuse code and add more flexibility:

    /**
     * This rule adds selected permissions to test app
     */
    
    public class PermissionsRule implements TestRule {
    
        private final String[] permissions;
    
        public PermissionsRule(String[] permissions) {
            this.permissions = permissions;
        }
    
        @Override
        public Statement apply(final Statement base, Description description) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
    
                    allowPermissions();
    
                    base.evaluate();
    
                    revokePermissions();
                }
            };
        }
    
        private void allowPermissions() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                for (String permission : permissions) {
                    InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
                            "pm grant " + InstrumentationRegistry.getTargetContext().getPackageName()
                                    + " " + permission);
                }
            }
        }
    
        private void revokePermissions() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                for (String permission : permissions) {
                    InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
                            "pm revoke " + InstrumentationRegistry.getTargetContext().getPackageName()
                                    + " " + permission);
                }
            }
        }
    }
    

    After that you can use this rule in your test classes:

    @Rule
    public final PermissionsRule permissionsRule = new PermissionsRule(
    new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS});
    

    Keep in mind:

    1. Rule does not affect on @Before methods because all rules are executed after that
    2. executeShellCommand is asynchronous and if you need accepted permissions right after test started consider adding some delay

提交回复
热议问题