Android Marshmallow引入的新权限方案需要在运行时检查特定权限,这意味着需要根据用户是拒绝还是允许访问来提供不同的流程。Android Marshmallow:用Espresso测试权限?
由于我们使用Espresso在我们的应用上运行自动UI测试,我们如何模拟或更新权限状态以测试不同的场景?
Android Marshmallow引入的新权限方案需要在运行时检查特定权限,这意味着需要根据用户是拒绝还是允许访问来提供不同的流程。Android Marshmallow:用Espresso测试权限?
由于我们使用Espresso在我们的应用上运行自动UI测试,我们如何模拟或更新权限状态以测试不同的场景?
给人以这样的静态方法一试,当您的手机是英语语言环境:
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 ");
}
}
}
}
我发现它here
其实有这样做的2种方式,我知道迄今:
adb shell pm grant "com.your.package" android.permission.your_permission
基于@riwnodennyk的解决方案,我们实现一个更好的。该接受的答案有两个问题:
所以,这里的最终解决方案:
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");
}
}
发现全班同学在这里:https://gist.github.com/rocboronat/65b1187a9fca9eabfebb5121d818a3c4
顺便说一句,因为这个答案一直是流行的,我们增加了PermissionGranter
到百瑞斯塔,我们上面的咖啡和UiAutomator工具,使仪器的测试绿色:https://github.com/SchibstedSpain/Barista检查出来,COS,我们将保持它通过释放释放。
试验是用类似运行之前,您可以授予权限:
@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-permissions
或pm revoke...
该进程被终止。
我在google测试示例代码中发现了类似的代码。它适用于该软件包中的电话手机示例应用程序,但如果在应用程序启动后立即询问权限(例如相机权限),则该功能无效。任何人有任何想法为什么? –
你可以试试@BeforeClass。 –
@ fangmobile.com也许是因为该活动也是在@ Before规则中开始的? – nickmartens1980
您可以通过在开始测试之前授予权限轻松实现这一点。例如,如果你都应该在试运行过程中使用的摄像头,您可以授权如下
@Before
public void grantPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getInstrumentation().getUiAutomation().executeShellCommand(
"pm grant " + getTargetContext().getPackageName()
+ " android.permission.CAMERA");
}
}
,您应该可以使用相同的方法撤销权限,这对我很有用!我必须查看清单以准确找出使用此技术授予的权限。 – jerimiah797
随着Android Testing Support Library 1.0的新版本,有一个GrantPermissionRule,你可以在你的测试使用前授予许可开始任何测试。
@Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
它在你的测试中起作用吗? –
是的,没有任何问题。 – Niklas
工程就像一个魅力!查看[此博客文章](http://kotlindevelopment.com/runtime-permissions-espresso-done-right/)了解更多信息。 –
我知道答案已经但是接受,而不是已经暗示了一遍又一遍,另一种更好的方法是做在实际测试中,你要对特定下面的if
声明, OS版本:
@Test
fun yourTestFunction() {
Assume.assumeTrue(Build.VERSION.SDK_INT >= 23)
// the remaining assertions...
}
如果assumeTrue
函数调用评估,以虚假的表情,测试将停止和被忽略,这我假设是你想要什么,此案正在设备上执行的测试pre SDK 23.
ESPRESSO UPDATE
这种单一的代码行授予列为立即生效授权方法参数 每权限。换句话说,应用程序 会像对待,如果权限已经授予 - 没有更多 对话框
@Rule @JvmField
val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION)
和gradle这个
dependencies {
...
testImplementation "junit:junit:4.12"
androidTestImplementation "com.android.support.test:runner:1.0.0"
androidTestImplementation "com.android.support.test.espresso:espresso-core:3.0.0"
...
}
参考:https://www.kotlindevelopment.com/runtime-permissions-espresso-done-right/
我已经实施了一个利用包装类的解决方案,覆盖并构建变体配置。解决方案需要很长时间才能解释,可以在这里找到:https://github.com/ahasbini/AndroidTestMockPermissionUtils。
现在还装在一个SDK,但主要的想法是重写的ContextWrapper.checkSelfPermission
和ActivityCompat.requestPermissions
的功能来进行操作和返回嘲笑结果欺骗应用到不同的场景,就像进行测试:许可的情况下,因此拒绝该应用程序请求并在授予许可的情况下结束。即使应用程序一直都有权限,但这种情况也会发生,但它的想法是被重写实现的模拟结果所欺骗。
此外,该实现还有一个名为PermissionRule
的TestRule
类,它可以在测试类中使用,以轻松模拟所有条件以无缝测试权限。例如,还可以确保应用程序称为requestPermissions()
。
可能重复[如何管理运行时权限android marshmallow espresso测试](http://stackoverflow.com/questions/32787234/how-to-manage-runtime-permissions-android-marshmallow-espresso-tests) – Caipivara
尝试这可能会对你有所帮助:-http://stackoverflow.com/a/41221852/5488468 –