Android 如何在仪器测试设备上放置测试数据文件?
在仪器(浓缩咖啡)测试之前,将测试数据文件上传到设备上的最佳/正确方式是什么 当用户选择设备文件系统上的某些文件时,我想测试应用程序的功能,我的应用程序正在处理这些文件,并为进一步的功能测试准备应用程序状态 我试图通过测试apk资产的第一次测试将其写入文件系统。但是,权限存在问题。我测试过的apk没有WRITE_EXTERNAL_存储,无论如何,我担心这不是一个好办法,因为现代安卓安全模型向用户发出交互式权限请求 也许我必须以某种方式将它集成到gradle脚本中 另外请注意,我有两种类型的测试:调试和登台(在启用minify的情况下测试apk) 我对一种适合Firebase测试实验室的方法很感兴趣Android 如何在仪器测试设备上放置测试数据文件?,android,testing,functional-testing,android-espresso,Android,Testing,Functional Testing,Android Espresso,在仪器(浓缩咖啡)测试之前,将测试数据文件上传到设备上的最佳/正确方式是什么 当用户选择设备文件系统上的某些文件时,我想测试应用程序的功能,我的应用程序正在处理这些文件,并为进一步的功能测试准备应用程序状态 我试图通过测试apk资产的第一次测试将其写入文件系统。但是,权限存在问题。我测试过的apk没有WRITE_EXTERNAL_存储,无论如何,我担心这不是一个好办法,因为现代安卓安全模型向用户发出交互式权限请求 也许我必须以某种方式将它集成到gradle脚本中 另外请注意,我有两种类型的测试:
谢谢。我找到了以下方法: 创建一些测试类,该类负责初始化并且必须首先运行。为了按特定顺序运行测试,我使用了如下的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中调用它
关键问题是权限。因此,您只需在TestenEnvironmentInitializer中使用这行代码
@Rule
public GrantPermissionRule runtimePermissionRule = GrantPermissionRule.grant(
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
当然,还要将此权限添加到应用程序AndroidManifest.xml中
我的问题是,最初测试的应用程序不应该具有写入外部存储权限
我没有找到解决这个问题的好办法。我已尝试仅为我的测试apk添加此权限。从逻辑上讲,因为我的TestenEnvironmentInitializer在测试apk中,所以我希望应该在测试apk中设置写权限。将具有此权限的测试apk AndroidManifest.xml片段放在src/androidTest下可以很容易地实现这一点
但这没有帮助。因为该权限应该在原始测试的apk中设置
所以我同意一些妥协。并将调试和暂存文件夹添加到src/folder下,并将具有写入权限的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脚本等,但我最终得到了上面的解决方案