【问题标题】:RuntimeException: Unable to create output dir: /storage/emulated/0/app_spoon-screenshotsRuntimeException:无法创建输出目录:/storage/emulated/0/app_spoon-screenshots
【发布时间】:2018-08-08 22:52:50
【问题描述】:

我正在使用 Spoon 2.0.0 快照使用 gradle-spoon-plugin 为 Android UI 测试设置 Spoon。我的项目是使用 Android Gradle 插件 3.0.1 设置的。

当通过spoonRule.screenshot(activity, "hello") 截屏时,我得到了这个 RuntimeException:

java.lang.RuntimeException: Unable to create output dir: /storage/emulated/0/app_spoon-screenshots
at com.squareup.spoon.SpoonRule.createDir(SpoonRule.java:167)
at com.squareup.spoon.SpoonRule.createDir(SpoonRule.java:164)
at com.squareup.spoon.SpoonRule.createDir(SpoonRule.java:164)
at com.squareup.spoon.SpoonRule.obtainDirectory(SpoonRule.java:108)
at com.squareup.spoon.SpoonRule.screenshot(SpoonRule.java:66)

如果我在 Nexus 4 API 19 模拟器上运行它,一切正常,但它不适用于 Pixel 2 API 27 模拟器。权限已从 19 更改为 27,因此这并不完全出乎意料。

我已经尝试了当前可用的大多数建议,包括在我的 androidTest 目录中添加一个清单,以授予读写外部存储(有和没有maxSdkVersion):

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="tv.twitch.android.test">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>

    <uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>

</manifest>

在这两种情况下,我都看到这些权限被合并到我的应用 AndroidManifest 的最终清单中(不确定如何检查测试应用的清单)。

我尝试通过 UIAutomator 向应用程序和测试包授予权限:

val device = UiDevice.getInstance(getInstrumentation())
device.executeShellCommand("pm grant tv.twitch.android.test android.permission.READ_EXTERNAL_STORAGE")
device.executeShellCommand("pm grant tv.twitch.android.debug android.permission.READ_EXTERNAL_STORAGE")
device.executeShellCommand("pm grant tv.twitch.android.test android.permission.WRITE_EXTERNAL_STORAGE")
device.executeShellCommand("pm grant tv.twitch.android.debug android.permission.WRITE_EXTERNAL_STORAGE")

这会向 Logcat 输出 Permission denied 并导致上述相同的异常。

如果我尝试利用 GrantPermissionRule 喜欢:

@get:Rule var runtimePermissionRule = GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)

我得到一个不同的例外:

junit.framework.AssertionFailedError: Failed to grant permissions, see logcat for details
at junit.framework.Assert.fail(Assert.java:50)
at android.support.test.runner.permission.PermissionRequester.requestPermissions(PermissionRequester.java:110)
at android.support.test.rule.GrantPermissionRule$RequestPermissionStatement.evaluate(GrantPermissionRule.java:108)

GrantPermissionCallable: Permission: android.permission.WRITE_EXTERNAL_STORAGE cannot be granted!

删除 Manifest.permission.WRITE_EXTERNAL_STORAGE 并只留下已读的,让我们回到原来的异常:java.lang.RuntimeException: Unable to create output dir: /storage/emulated/0/app_spoon-screenshots

在 Android Studio 中或在命令行上使用 gradle-spoon-plugin 运行不会影响上述任何一项。

查看我的应用程序和测试应用程序在设置中授予的权限,我看到我的应用程序具有存储权限,但我的测试应用程序 (tv.twitch.android.test) 没有任何请求的权限。

我也尝试过使用Barista 库:

PermissionGranter.allowPermissionsIfNeeded(Manifest.permission.WRITE_EXTERNAL_STORAGE)

他们也没有运气。

更新:

我尝试让我的测试应用以 SDK 版本 22 为目标,希望它能获得写入权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="tv.twitch.android.test">

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22"
        tools:overrideLibrary="android.support.test.uiautomator.v18"/>

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

</manifest>

通过 Gradle (./gradlew spoon) 我尝试配置 gradle-spoon-plugin 以请求所有权限:

spoon {
    // Grant all runtime permissions during installation on Marshmallow and above devices.
    grantAll = true
}

没有运气。我什至尝试使用 Spoon 库版本 1.3.1 也无济于事。

【问题讨论】:

    标签: android ui-testing spoon barista


    【解决方案1】:

    我的问题是由具有 WRITE_EXTERNAL_STORAGE 权限的外部库合并到 maxSdkVersion 引起的。为了解决这个问题,我删除了该属性并重新添加了 WRITE_EXTERNAL_STORAGE 权限。这只需要我的应用程序清单,而不是测试应用程序清单。

    <!-- Strip away maxSdkVersion -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                     tools:remove="android:maxSdkVersion"/>
    
    <!-- Add the permission with no maxSdkVersion defined -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    然后您可以构建、授予权限并运行测试:

    # Uninstall existing APKs and install our app APK and test APK
    ./gradlew uninstallAll installDebug installDebugAndroidTest
    
    # List all APKs installed with adb shell 'pm list packages -f'
    # Grant the app APK write and read to external storage permissions
    adb shell pm grant gg.mark.debug android.permission.WRITE_EXTERNAL_STORAGE
    adb shell pm grant gg.mark.debug android.permission.READ_EXTERNAL_STORAGE
    
    export APK=build/outputs/apk/debug/debug.apk
    export TEST_APK=build/outputs/apk/androidTest/debug/debug-androidTest.apk
    
    # TEST_APK and APK are positional arguments so keep them in this order
    # Disable GIF generation because it's slow
    java -jar spoon-runner-2.0.0.jar --debug --disable-gif "$TEST_APK" "$APK"
    

    如果您的应用的权限未在合并的 AndroidManifest.xml 中正确设置,pm grant 命令将失败。确保这些命令成功!

    【讨论】:

      【解决方案2】:

      首先,尝试在Pixel2(API27)上找到SystemSetting-&gt;YOUR_APP-&gt;Permission,检查外部存储是否被禁用。

      API23(Android 6+)之后的运行时需要EXTERNAL_STORAGEWRITEREAD)的权限。您应该检查权限并通知用户在系统配置中启用。见Request App Permissions

      当然,普通应用程序没有权限像往常一样使用pm grant ... 授予其权限。

      一个不推荐的解决方案是让整个应用程序以 API22 为目标。但正确的方法也是检查权限并通知用户。

      【讨论】:

      • 在设置中,我的应用程序正在正确请求存储权限,但测试应用程序不是,这可能是问题所在。我不确定测试应用是否应该像您链接的文档一样显示请求权限对话框?
      • @Mark 是的,权限对话框是自定义对话框,而不是系统。应用程序中指示用户启用其权限的方式是开发人员部分职责(在谷歌眼中)。如果在 Pixel2 系统配置(不是您的应用清单)中启用您的应用权限,您应该测试是否有效。或者让 TargetApi = 22 来确认是否真的是这个原因。
      • 抱歉没有看到properly requesting Storage permissions。您是否尝试将 TargetApi 设置为 22?
      猜你喜欢
      • 1970-01-01
      • 2021-09-04
      • 2016-07-05
      • 2021-06-07
      • 1970-01-01
      • 2022-10-02
      • 1970-01-01
      • 2014-06-30
      • 2020-11-03
      相关资源
      最近更新 更多