Cha*_* Li 13 android android-testing android-permissions android-espresso android-uiautomator
我正在使用Espresso和UIAutomator来编写我的测试用例.我正在测试外部存储权限,当它被拒绝时以及何时被允许.我有不同的测试用例,都需要在测试用例开始时撤销权限.但是,某些测试用例应该并且确实会导致授予权限,因此我需要在执行下一个测试时撤消权限.我一直在搜索,我遇到的最接近的事情是使用pm管理器执行adb shell命令来撤销权限.但是,通过这样做,我将收到以下错误,由于"进程崩溃",Instrumentation运行失败.有没有什么办法可以确保在每个测试用例开始时撤销权限?如果没有,如何解决有关测试权限的问题?提前谢谢你的帮助!
这是我目前在每个测试用例之前撤消权限的代码片段(不起作用):
@Before
public void setUp() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getInstrumentation().getUiAutomation().executeShellCommand(
"pm revoke " + getTargetContext().getPackageName()
+ " android.permission.WRITE_EXTERNAL_STORAGE");
}
}
Run Code Online (Sandbox Code Playgroud)
尝试使用上面的代码段撤消权限时出现相应的错误消息:
Test failed to run to completion. Reason: 'Instrumentation run failed due to 'Process crashed.''.
Run Code Online (Sandbox Code Playgroud)
ADB 具有撤销权限的功能,但无法从仪器测试中调用它,因为撤销权限将重新启动整个应用程序进程并以失败结束测试。以下 Kotlin 代码将执行撤销,但如果权限被撤销,您的测试将会崩溃。
/**
* Will revoke, but also CRASH if called by a test
* Revocation requires a full process restart, which crashes your test process.
*/
fun revokePermissions(vararg permissions: String) {
permissions.forEach {
InstrumentationRegistry.getInstrumentation().uiAutomation.
executeShellCommand("pm revoke ${getTargetContext().packageName} $it")
}
}
Run Code Online (Sandbox Code Playgroud)
如果您从 shell 脚本运行测试,则只需在开始每个测试之前使用以下 shell 命令之一即可。
adb shell pm revoke com.package.appname android.permission.CAMERA
adb shell pm reset-permissions com.package.appname
adb shell pm clear com.package.appname
Run Code Online (Sandbox Code Playgroud)
无论您是从自定义 AndroidJUnitRunner 的 onCreate() 或 onStart() 撤销权限,还是从测试中间撤销权限,都会发生相同的崩溃。即使活动尚未打开,您也无法在仪器测试期间撤销权限而不崩溃。
似乎最好的选择是在运行任何仪器测试之前撤销 Gradle 的所有权限,然后您可以在测试开始之前使用 GrantPermissionRule 重新启用您想要设置的任何权限。
Android Test Orchestrator计划在每次测试之间自动清除所有数据,但目前该功能仍然不存在。我提交了一个错误,您可以投票以在测试之间进行自动清理。
在测试开始之前,您不应撤消任何许可。这将重新启动整个测试应用程序过程,并且该测试将标记为失败。
相反,您可以在测试执行完成后即@After通过如下方法撤消许可:
@After
fun tearDown(){
InstrumentationRegistry.getInstrumentation().uiAutomation.
executeShellCommand("pm revoke ${getTargetContext().packageName} android.permission.WRITE_EXTERNAL_STORAGE")
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用Android Test Orchestrator 1.0.2版并进行设置
testInstrumentationRunnerArguments clearPackageData: 'true'
Run Code Online (Sandbox Code Playgroud)
这将在每次测试后清除包装数据。
注意:v1.0.2在通过Jacoco管理代码覆盖率报告时,Android Test Orchestrator 出现问题。
小智 2
我不确定如何在运行时执行此操作而不提示用户。但是,您在标题中指出这是为了测试目的。因此我有一些选择可以建议你
a)当需要在没有权限的情况下进行测试时,只需使用设备的设置手动撤销即可。
b) 您可以检查并请求许可,然后拒绝许可。我会给你一些代码,我用它来检查并请求相机许可。您只需要更改权限名称,也许还有要检查的条件:
public static boolean checkCameraPermission(MainActivity thisActivity) {
return ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED;
}
public static void checkAndAskCameraPermission(final MainActivity thisActivity) {
if (!checkCameraPermission(thisActivity)) {
//No right is granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.CAMERA)) {
//Open a dialog explaining why you are asking permission then when when positive button is triggered, call this line
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.CAMERA},
CHECK_FOR_CAMERA_PERMISSION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.CAMERA},
CHECK_FOR_CAMERA_PERMISSION);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要的话,我可以给您更多关于 b)(如何请求权限)的链接(只需评论即可)。但是,由于我不确定您是否会对这个答案感兴趣,因此我不会花时间来记录此选项。
但是,也许有人能够向您解释如何在运行时直接执行此操作而无需提示,但我认为至少向您提供这些信息可能会很有趣。
| 归档时间: |
|
| 查看次数: |
3435 次 |
| 最近记录: |