提问者:小点点

如何管理运行时权限AndroidMarshmallow浓缩咖啡测试


我正在使用浓缩咖啡进行测试,但有时我会尝试从外部存储获取图像,并且使用Marshmallow我需要运行时权限,否则会出现异常崩溃并且测试将失败。

androidTestCompile 'com.android.support.test:runner:0.4'
androidTestCompile 'com.android.support.test:rules:0.4'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.1'
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.1') {
    // this library uses the newest app compat v22 but the espresso contrib still v21.
    // you have to specifically exclude the older versions of the contrib library or
    // there will be some conflicts
    exclude group: 'com.android.support', module: 'appcompat'
    exclude group: 'com.android.support', module: 'support-v4'
    exclude module: 'recyclerview-v7'
}
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'com.squareup.retrofit:retrofit-mock:1.9.0'
androidTestCompile 'com.squareup.assertj:assertj-android:1.1.0'
androidTestCompile 'com.squareup.spoon:spoon-client:1.2.0'

我怎样才能正确管理它?

我应该为运行时权限编写测试还是有办法禁用它进行测试?

我应该像她在这里所说的那样在测试运行之前授予权限吗?https://www.youtube.com/watch?list=PLWz5rJ2EKKc-lJo_RGGXL2Psr8vVCTWjM


共3个答案

匿名用户

更新!现在,您可以使用 Android 测试支持库中的规则

它比自定义规则更合适。

过时的答案:

您可以添加测试规则以重用代码并增加更多灵活性:

/**
 * 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);
            }
        }
    }
}

之后,您可以在测试类中使用此规则:

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

请记住:

  1. 规则不会影响@Before方法,因为所有规则都在此之后执行
  2. executeShellCommand 是异步的,如果您在测试开始后立即需要接受的权限,请考虑添加一些延迟

匿名用户

您可以使用以下方法授予和撤消权限:

adb shell pm grant com.package.myapp android.permission.<PERMISSION>
adb shell pm revoke com.package.myapp android.permission.<PERMISSION>

若要从 Java 进行检测测试,请从 Google 示例中调用此方法:https://github.com/googlesamples/android-testing/blob/ed62c450e43f859333b3113d44dd59f75971b529/ui/espresso/IntentsBasicSample/app/src/androidTest/java/com/example/android/testing/espresso/BasicSample/DialerActivityTest.java#L94

匿名用户

您可以使用 GrantPermissionRule。此规则将为该测试类中的所有测试方法授予所有请求的运行时权限。

@Rule 
public GrantPermissionRule mRuntimePermissionRule
            = GrantPermissionRule.grant(Manifest.permission.READ_PHONE_STATE);