Android Marshmallow : Espresso로 권한을 테스트 하시겠습니까?
Android Marshmallow에서 도입 한 새로운 권한 체계는 런타임시 특정 권한을 확인해야합니다. 이는 사용자가 액세스를 거부하거나 허용하는지 여부에 따라 다른 흐름을 제공해야 함을 의미합니다.
Espresso를 사용하여 앱에서 자동화 된 UI 테스트를 실행할 때 다양한 시나리오를 테스트하기 위해 권한 상태를 어떻게 모의하거나 업데이트 할 수 있습니까?
Android 테스트 지원 라이브러리 1.0 의 새 릴리스에는 테스트를 시작하기 전에 권한을 부여하기 위해 테스트에서 사용할 수 있는 GrantPermissionRule 이 있습니다.
@Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
Kotlin 솔루션
@get:Rule var permissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION)
@get:Rulejava.lang.Exception: The @Rule 'permissionRule' must be public.더 많은 정보는 여기 에서 피하기 위해 사용되어야합니다 .
허용 된 대답은 실제로 권한 대화 상자를 테스트하지 않습니다. 그냥 우회합니다. 따라서 어떤 이유로 권한 대화 상자가 실패하면 테스트에서 거짓 녹색이 표시됩니다. 전체 앱 동작을 테스트하기 위해 실제로 "권한 부여"버튼을 클릭하는 것이 좋습니다.
이 솔루션을 살펴보십시오.
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
그런데이 답변이 인기가 많았 기 때문에 Espresso 및 UiAutomator 위에있는 도구 인 Barista에 추가 PermissionGranter하여 도구 테스트를 녹색으로 만들었습니다. https://github.com/SchibstedSpain/Barista 확인하십시오. 릴리스 별 릴리스.
전화기가 영어 로케일 일 때 이러한 정적 방법을 사용해보십시오.
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 ");
}
}
}
}
여기 에서 찾았습니다
테스트를 실행하기 전에 다음과 같은 권한을 부여 할 수 있습니다.
@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...프로세스가 종료 되면 .
실제로 지금까지 알고있는 두 가지 방법이 있습니다.
- 테스트를 시작하기 전에 adb 명령을 사용하여 권한을 부여합니다 ( documentation ).
adb shell pm grant "com.your.package" android.permission.your_permission
- 권한 대화 상자를 클릭하고 UIAutomator ( 문서 )를 사용하여 권한을 설정할 수 있습니다 . 테스트가 Android 용 Espresso로 작성된 경우 Espresso 및 UIAutomator 단계를 하나의 테스트로 쉽게 결합 할 수 있습니다.
테스트를 시작하기 전에 권한을 부여하면 쉽게 수행 할 수 있습니다. 예를 들어 테스트 실행 중에 카메라를 사용해야하는 경우 다음과 같은 권한을 부여 할 수 있습니다.
@Before
public void grantPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getInstrumentation().getUiAutomation().executeShellCommand(
"pm grant " + getTargetContext().getPackageName()
+ " android.permission.CAMERA");
}
}
에스프레소 업데이트
This single line of code grants every permission listed as parameter in the grant method with immediate effect. In other words, the app will be treated like if the permissions were already granted - no more dialogs
@Rule @JvmField
val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION)
and 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"
...
}
reference: https://www.kotlindevelopment.com/runtime-permissions-espresso-done-right/
I know an answer has been accepted, however, instead of the if statement that has been suggested over and over again, another more elegant approach would be to do the following in the actual test you want for a specific version of OS:
@Test
fun yourTestFunction() {
Assume.assumeTrue(Build.VERSION.SDK_INT >= 23)
// the remaining assertions...
}
If the assumeTrue function is called with an expression evaluating to false, the test will halt and be ignored, which I am assuming is what you want in case the test is being executed on a device pre SDK 23.
I've implemented a solution which leverages wrapper classes, overriding and build variant configuration. The solution is quite long to explain and is found over here: https://github.com/ahasbini/AndroidTestMockPermissionUtils.
It is not yet packed in an sdk but the main idea is to override the functionalities of ContextWrapper.checkSelfPermission and ActivityCompat.requestPermissions to be manipulated and return mocked results tricking the app into the different scenarios to be tested like: permission was denied hence the app requested it and ended with granted permission. This scenario will occur even if the app had the permission all along but the idea is that it was tricked by the mocked results from the overriding implementation.
Furthermore the implementation has a TestRule called PermissionRule class which can be used in the test classes to easily simulate all of the conditions to test the permissions seamlessly. Also assertions can be made like ensuring the app has called requestPermissions() for example.
There is GrantPermissionRule in Android Testing Support Library, that you can use in your tests to grant a permission before starting any tests.
@Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.CAMERA, android.Manifest.permission.ACCESS_FINE_LOCATION);
Thank you @niklas for the solution. In case anyone looking to grant multiple permissions in Java:
@Rule
public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CAMERA);
참고URL : https://stackoverflow.com/questions/33929937/android-marshmallow-test-permissions-with-espresso
'Program Club' 카테고리의 다른 글
| 상단에 행을 삽입 할 때 uitableview를 정적으로 유지 (0) | 2020.12.03 |
|---|---|
| Html.Hidden과 Html.HiddenFor의 차이점은 무엇입니까? (0) | 2020.12.03 |
| iPhone SDK에 새 글꼴을 포함하고 사용하는 방법은 무엇입니까? (0) | 2020.12.02 |
| 가변 깊이가있는 다단계 defaultdict? (0) | 2020.12.02 |
| jQuery javascript regex 다음으로 바꾸기 (0) | 2020.12.02 |