在CI中具有存储权限的Android UI测试

时间:2018-10-24 19:36:57

标签: android jenkins-pipeline ui-testing

我想在CI(Jenkins Pipeline)中的一个项目上运行UI测试和单元测试。 UI测试要求图像和视频必须位于测试设备/仿真器上。在UI测试中,我请求获得存储读/写访问权限,因此我可以将一些资产转储到downloads文件夹中,然后在测试套件结束时将其删除。

当我在Jenkins(mac)上运行测试时,未授予权限,没有介质传输,并且所有测试都失败了。

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

管道步骤

构建

 function createTest()
{
  var templateFile = DriveApp.getFileById("ID");
  templateFile.makeCopy("NAME", DriveApp.getFoldersByName("FOLDERNAME").next())
}

单元测试

sh "./gradlew clean assembleRelease"

UI测试

sh "./gradlew testReleaseUnitTest"

问题

1)CI构建挂在隐式sh "$ANDROID_HOME/emulator/emulator @my_sweet_emulator_name -no-boot-anim & $ANDROID_HOME/platform-tools/adb wait-for-device" sh './gradlew connectedAndroidTest' 任务上

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

我尝试过的事情

  • 我仅尝试测试发行版,但这显示了相同的问题2。assembleDebugAndroidTest
  • 我没有其他需要使用的权限

我如何授予权限

testBuildType "release"

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

1 个答案:

答案 0 :(得分:0)

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

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

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

并尝试执行以下检测的测试用例/类:

@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"))
    }
}

两个测试用例均成功返回。将rootDir更改为"/"后,由于/目录是只读目录,因此测试失败。

拥有两个测试用例的想法是测试不同的Context,这些测试可以在运行时检索到。 testTargetContextPermission使用的应用程序Context 没有,其软件包名称或应用程序ID以.test结尾。 testInstrumentationPermission使用检测应用程序Context,它确实具有程序包名称或以.test结尾的应用程序ID。我认为需要在他们的每个AndroidManifest中定义权限,但是事实证明,只为app AndroidManifest定义权限也将自动为Instrumentation包赋予相同的权限。