如何将测试数据文件放在设备上进行仪器测试?

时间:2018-03-19 12:53:29

标签: android testing functional-testing android-espresso

在仪器(Espresso)测试之前,将测试数据文件上传到设备的最佳/正确方法是什么?

当用户选择设备文件系统上的某些文件并且我的应用正在处理这些文件并准备应用状态以进行进一步的功能测试时,我想测试应用功能。

我尝试通过测试apk资产的第一个测试将其写入文件系统。但是权限存在问题。我测试的apk没有WRITE_EXTERNAL_STORAGE,无论如何我担心这是不好的方式,因为现代Android安全模型带有交互式权限请求给用户。

可能我必须以某种方式将它集成到gradle脚本中?

另请注意我有两种类型的测试:调试和暂存(用minifyEnabled测试apk)

我对Firebase测试实验室的方法感兴趣。

谢谢。

1 个答案:

答案 0 :(得分:0)

我找到了以下方法: 创建一个负责初始化的测试类,必须先运行。要按特定顺序运行测试,我使用的Suite类如下:

@RunWith(Suite.class)
@Suite.SuiteClasses({TestEnvironmentInitializer.class,
        FirstTest.class,
        SecondTest.class
})
public class MyTestSuite {
}

可以从cmd运行:

 ./gradlew yourappmodule:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=your.package.androidtest.MyTestSuite 

或者如果您想测试apk接近发布(使用minifyEnabled去除等)并使用testBuildType“staging”,您可以调用它:

./gradlew yourappmodule:connectedStagingAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=your.package.androidtest.MyTestSuite 

虽然还有许多与此问题无关的其他问题。例如。要运行测试,你必须保留一些可以在发布版本中删除的类和方法,以及apk符号等。

您肯定可以直接从Android Studio

调用它

关键问题是权限。所以你只需要在TestEnvironmentInitializer中使用这行代码

@Rule
public GrantPermissionRule runtimePermissionRule = GrantPermissionRule.grant(
        Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE);

当然,将此权限添加到应用AndroidManifest.xml

我的问题是原始测试的应用程序不应该具有WRITE_EXTERNAL_STORAGE权限。

我找不到解决此问题的好方法。我试图仅为我的测试apk添加此权限。在逻辑上,因为我的TestEnvironmentInitializer在测试apk中我期望应该在测试apk中设置WRITE权限。这可以很容易地实现在src / androidTest下使用此权限的测试apk AndroidManifest.xml片段 但它没有帮助。因为此权限应在原始测试的apk中设置。

所以我同意妥协。并在src /文件夹下添加debug和staging文件夹,并将具有WRITE权限的AndroidManifest.xml片段放在那里。 因此,当我运行我的测试时,它们可以作为调试或暂存运行,并且存在权限。但是它不会出现在真正的版本中。

我已将测试数据文件添加到src / androidTest

下的assets文件夹中

以下是我的初始化程序测试示例:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class TestEnvironmentInitializer {

    @Rule
    public GrantPermissionRule runtimePermissionRule = GrantPermissionRule.grant(
            Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE);


    @Test
    public void initEnvironment() {
        try {

            Context testContext = InstrumentationRegistry.getInstrumentation().getContext();


            File root = Environment.getExternalStorageDirectory();


            File testDataFolder = new File(root, "testData");

            if(testDataFolder.mkdirs()) {

                File destFile = new File(testDataFolder, "test_data.dat");
                if (!destFile.exists()) {
                    copyAssetToExternalStorage(testContext, "assetssubfolder/test_data.dat", destFile);
                }
            }

        } catch (Throwable e) {
            System.exit(-1);
        }
    }

    void copyAssetToExternalStorage(Context context, String fileToCopy, File dest) throws
            IOException {

        try (InputStream src = context.getAssets().open(fileToCopy)) {

            try (FileOutputStream destStream = new FileOutputStream(
                    dest)) {

                copyStream(src, destStream);
            }
        }
    }

    void copyStream(InputStream src, OutputStream dest) throws IOException {

        byte[] buffer = new byte[1024];
        int read;
        while ((read = src.read(buffer)) != -1) {
            dest.write(buffer, 0, read);
        }
    }
}

旧设备只是忽略了GrantPermissionRule,因此它足以获得应用清单中的权限。

还有其他想法,例如更改gradle脚本等。但我最终得到了上面的解决方案。