Android UI使用CI中的存储权限进行测试

Sab*_*ado 8 android ui-testing jenkins-pipeline

我想在CI(Jenkins Pipeline)中的项目上运行UI测试和单元测试.UI测试要求图像和视频位于测试设备/仿真器上.在UI测试中,我请求存储读/写访问权限,因此我可以将一些资源转储到下载文件夹中,然后在测试套件的末尾将其删除.

当我在Jenkins(mac)上运行我的测试时,没有授予权限,没有媒体转移,我的所有测试都失败了.

该项目包含一个应用程序模块和两个内部库模块.

管道步骤

建立

sh "./gradlew clean assembleRelease"
Run Code Online (Sandbox Code Playgroud)

单元测试

sh "./gradlew testReleaseUnitTest"
Run Code Online (Sandbox Code Playgroud)

UI测试

sh "$ANDROID_HOME/emulator/emulator @my_sweet_emulator_name -no-boot-anim & $ANDROID_HOME/platform-tools/adb wait-for-device"
sh './gradlew connectedAndroidTest'
Run Code Online (Sandbox Code Playgroud)

问题

1)CI构建依赖于隐式assembleDebugAndroidTest任务

2)如果我在计算机的命令行上运行该任务,则测试将安装但是未授予读/写存储权限,因此所有测试都因设备上没有任何预期内容而失败.

我试过的事情

  • 我曾尝试仅测试发布版本,但这显示了相同的问题2. testBuildType "release"
  • 我没有其他权限需要处理

我如何授予权限

@RunWith(AndroidJUnit4::class)
class MyMediaClassTest {

    @Rule
    @JvmField
    val activityRule = ActivityTestRule(MainActivity::class.java)

    @Rule
    @JvmField
    val grantPermissionRule: GrantPermissionRule = GrantPermissionRule
            .grant(android.Manifest.permission.READ_EXTERNAL_STORAGE,
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
// tests and stuff
}
Run Code Online (Sandbox Code Playgroud)

我已经看到了一个短期解决方案,可以将我的所有媒体资产手动复制到模拟器中.但这似乎不对,这应该能够实现自动化.

aha*_*ini 2

它与我合作的方式是按照以下步骤操作:

AndroidManifest.xml在我的模块的文件中添加了权限app

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Run Code Online (Sandbox Code Playgroud)

并尝试执行以下仪器测试用例/类:

@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {

    @Rule
    @JvmField
    val grantPermissionRule: GrantPermissionRule = GrantPermissionRule
            .grant(android.Manifest.permission.READ_EXTERNAL_STORAGE,
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE)

    val rootDir = "/sdcard/"

    @Test
    fun testTargetContextPermission() {
        val targetContext = InstrumentationRegistry.getTargetContext()
        assertTrue("Not the target package",
                !targetContext.packageName.endsWith(".test"))
        assertTrue("Permissions not Granted", targetContext.checkSelfPermission(
                android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
                targetContext.checkSelfPermission(
                        android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
        val file = File(rootDir + "targetTest.txt")
        if (file.exists()) {
            file.delete()
        }
        assertTrue("File was not created", file.createNewFile())
        val sdcard = File(rootDir)
        assertTrue("sdcard is empty or file not found", sdcard.list().size != 0 &&
                Arrays.asList<String>(*sdcard.list()).contains("targetTest.txt"))
    }

    @Test
    fun testInstrumentationPermission() {
        val instrumentationContext = InstrumentationRegistry.getContext()
        assertTrue("Not the instrumentation package",
                instrumentationContext.packageName.endsWith(".test"))
        assertTrue("Permissions not Granted", instrumentationContext.checkSelfPermission(
                android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
                instrumentationContext.checkSelfPermission(
                        android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
        val file = File(rootDir + "instrumentationTest.txt")
        if (file.exists()) {
            file.delete()
        }
        assertTrue("File was not created", file.createNewFile())
        val sdcard = File(rootDir)
        assertTrue("sdcard is empty or file not found", sdcard.list().size != 0 &&
                Arrays.asList<String>(*sdcard.list()).contains("instrumentationTest.txt"))
    }
}
Run Code Online (Sandbox Code Playgroud)

两个测试用例均成功返回。更改为 后rootDir"/"测试失败,因为该/目录是预期的只读目录。

拥有两个测试用例背后的想法是Context测试测试可以在运行时检索的不同内容。使用testTargetContextPermission的应用程序的包名称或应用程序 IDContext.test. 虽然testInstrumentationPermission使用的仪器应用程序Context确实其包名称或应用程序 ID 以.test. 我认为需要在每个AndroidManifests 中定义权限,但事实证明,仅为您定义权限app AndroidManifest也会自动为 Instrumentation 包授予相同的权限。