Android Marshmallow:用Espressotesting权限?

Android Marshmallow引入的新权限scheme需要在运行时检查特定权限,这意味着需要根据用户拒绝还是允许访问来提供不同的stream程。

当我们使用Espresso在我们的应用程序上运行自动UItesting时,我们如何模拟或更新权限的状态以testing不同的场景?

当您的手机处于英文区域设置时,请尝试使用这种静态方法:

private static void allowPermissionsIfNeeded() { if (Build.VERSION.SDK_INT >= 23) { UiDevice device = UiDevice.getInstance(getInstrumentation()); UiObject allowPermissions = device.findObject(new UiSelector().text("Allow")); if (allowPermissions.exists()) { try { allowPermissions.click(); } catch (UiObjectNotFoundException e) { Timber.e(e, "There is no permissions dialog to interact with "); } } } } 

我在这里find了

基于@riwnodennyk解决scheme,我们实现了一个更好的。 接受的答案有两个问题:

  • 如果设备不是英文的,它将不起作用
  • 如果您之前已经允许这个权限,但是您的应用程序有一个文本为“允许”的button,那么每次testing都会被点击,不pipe是否是权限对话框。

所以,这是最后的解决scheme:

 public static void allowPermissionsIfNeeded(String permissionNeeded) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasNeededPermission(permissionNeeded)) { sleep(PERMISSIONS_DIALOG_DELAY); UiDevice device = UiDevice.getInstance(getInstrumentation()); UiObject allowPermissions = device.findObject(new UiSelector() .clickable(true) .checkable(false) .index(GRANT_BUTTON_INDEX)); if (allowPermissions.exists()) { allowPermissions.click(); } } } catch (UiObjectNotFoundException e) { System.out.println("There is no permissions dialog to interact with"); } } 

在这里find全class: https : //gist.github.com/rocboronat/65b1187a9fca9eabfebb5121d818a3c4

顺便说一句,因为这个答案是一个受欢迎的,我们添加了PermissionGranter Barista ,我们的工具上面的Espresso和UiAutomator使仪器testing绿色: https : //github.com/SchibstedSpain/Barista检查出来,因为我们将维护它释放释放。

您可以在testing运行之前授予权限,如下所示:

 @Before public void grantPhonePermission() { // In M+, trying to call a number will trigger a runtime dialog. Make sure // the permission is granted before running this test. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { getInstrumentation().getUiAutomation().executeShellCommand( "pm grant " + getTargetContext().getPackageName() + " android.permission.CALL_PHONE"); } } 

但是你不能撤销。 如果您尝试pm reset-permissionspm revoke...进程被杀害。

随着Androidtesting支持库1.0的新版本,有一个GrantPermissionRule ,您可以在您的testing中使用GrantPermissionRule授予权限,然后开始任何testing。

 @Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION); 

实际上到目前为止,有两种方法可以做到这一点:

  1. 在testing开始之前使用adb命令授予权限( 文档 ):

adb shell pm grant "com.your.package" android.permission.your_permission

  1. 您可以点击权限对话框并使用UIAutomator设置权限( 文档 )。 如果您的testing是用Espresso for Android编写的,您可以轻松地将Espresso和UIAutomator步骤组合在一个testing中。

在开始testing之前,您可以轻松实现这一点。 例如,如果您在testing运行期间应该使用相机,则可以按如下方式授予权限

 @Before public void grantPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { getInstrumentation().getUiAutomation().executeShellCommand( "pm grant " + getTargetContext().getPackageName() + " android.permission.CAMERA"); } } 

我在这里使用espresso和adbtesting之前和之后禁用和恢复animation的尺度,

而且看起来像Stony Wang在这里所做的那样,Denys也回答了M的权限。

我知道一个答案已经被接受,但是,而不是一再提出的if语句,另一个更优雅的方法是在特定版本的操作系统的实际testing中执行以下操作:

 @Test fun yourTestFunction() { Assume.assumeTrue(Build.VERSION.SDK_INT >= 23) // the remaining assertions... } 

如果使用expression式评估为false来调用assumeTrue函数,那么testing将暂停并被忽略,我假定这是您在设备上预先testingSDK 23时所需的。