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 Exception crash and the test will fail.
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'
how can I manage that right?
should I write test for Runtime permissions or there's a way to disable it for testing?
should I give permissions before the tests run like she says here? https://www.youtube.com/watch?list=PLWz5rJ2EKKc-lJo_RGGXL2Psr8vVCTWjM&v=C8lUdPVSzDk
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: