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 –