Skip to content

Testing Runtime Permissions

jksiezni edited this page Jan 4, 2017 · 3 revisions

Warning: The library is highly experimental. So, it may fail with more advanced test cases.

Permissive Testing library provides an easy way to overcome problem of handling Runtime Permissions in UI tests. It allows to fully test all scenarios related to permissions.

The library was designed to work with Espresso and utilizes latest Espresso dependencies by itself.

Why do you need it?

There are multiple problems related to automated UI testing with Runtime Permissions. But the main issue arises, when a once granted permission must be reset, because it force closes the app process and prevents from running further tests. The Permissive Testing library attempts to solve this issue by separating tested app from system managed permissions.

How it works?

To achieve it, the library replaces Android's permissions handling with it's own fake permissions handling. It is possible thanks to Espresso Intents stubbing and some fancy Context impersonation for tested Activities. In effect, it allows to intercept all checks and requests for permissions and return fake results. So, when the app asks for a permission, no system dialog is displayed, but a predefined result is returned instead.

Setup

It is assumed that you are familiar with Espresso testing framework and you already have setup project to use Espresso.

  • Add it in your build.gradle at the end of repositories:
repositories {
    maven { url "https://jitpack.io" }
}
  • Add the Permissive Testing library to dependencies (make sure to use androidTestCompile configuration):
dependencies {
    androidTestCompile 'com.github.jksiezni.permissive:permissive-testing:0.2'
}

Usage

To start using Permissive Testing library, add to your Test class a PermissiveTestRule:

@Rule
public PermissiveTestRule<MainActivity> mActivityTestRule = new PermissiveTestRule<>(MainActivity.class);

If you already have a test class with declared ActivityTestRule, then you can simply replace it with PermissiveTestRule. This rule is mandatory for the library to work, because it makes sure that the Activity receives fake permissions.

Example 1

Writing a test case with all permissions granted.

By default the PermissiveTestRule denies all permissions. This behavior can be changed by chaining granted(String permission) methods or using grantedAll() to grant all permissions that were declared in the Android Manifest.

@Rule
public PermissiveTestRule<MainActivity> mActivityTestRule = new PermissiveTestRule<>(MainActivity.class)
    .grantedAll();

Example 2

Writing a test case with a permission request.

In this case, you need to prepare a response for a permission request. Every time before such a request you need to use one of espresso-like methods from PermissiveTesting. The onPermissionRequest allows to setup a response for a single permission request. For multiple permissions use onMultiplePermissionsRequest method.

@Rule
public PermissiveTestRule<MainActivity> mActivityTestRule = new PermissiveTestRule<>(MainActivity.class);

@Test
public void grant_permission() {
    assertThat(Manifest.permission.CAMERA, is(denied()));
    onPermissionRequest(Manifest.permission.CAMERA).grant();

    onView()... // perform some action that would request a permission

    assertThat(Manifest.permission.CAMERA, is(granted()));
}

Hamcrest matchers

The library also provides hamcrest matchers for asserting a proper permission before a test is performed. However, they are matched against fake permissions. The PermissiveMatchers class provides granted() and denied() matchers, that can be used like this:

    assertThat(Manifest.permission.CAMERA, is(denied()));
    assertThat(Manifest.permission.CAMERA, is(granted()));
Clone this wiki locally