在 InstrumentationTestCase 运行之间重置应用程序状态
Reset app state between InstrumentationTestCase runs
我的一位 QA 工程师正在支持一个具有相当大的代码库和许多不同的 SharedPreferences 文件的应用程序。前几天他来找我询问如何在测试运行之间重置应用程序状态,就好像它已被卸载-重新安装一样。
Espresso(他正在使用)和 Android 测试框架本身都不支持,所以我不确定该告诉他什么。使用本机方法来清除所有不同的 SharedPreferences 文件将是一个非常脆弱的解决方案。
如何在检测期间重置应用程序状态?
当前的 espresso 不提供任何重置应用程序状态的机制。但是对于每个方面(pref、db、文件、权限)都存在一个解决方案。
一开始你必须避免浓缩咖啡自动启动你的 activity 这样你就有足够的时间重新设置。
@Rule
public ActivityTestRule<Activity> activityTestRule = new ActivityTestRule<>(Activity.class, false, false);
然后用
开始你的 activity
activityTestRule.launchActivity(null)
要重置首选项,您可以使用以下代码段(在开始 activity 之前)
File root = InstrumentationRegistry.getTargetContext().getFilesDir().getParentFile();
String[] sharedPreferencesFileNames = new File(root, "shared_prefs").list();
for (String fileName : sharedPreferencesFileNames) {
InstrumentationRegistry.getTargetContext().getSharedPreferences(fileName.replace(".xml", ""), Context.MODE_PRIVATE).edit().clear().commit();
}
您也可以在启动 activity 后重置首选项。但是 activity 可能已经阅读了首选项。
您的应用程序 class 只启动了一次,并且在您可以重置首选项之前已经启动。
我已经开始编写一个库,它应该使使用 espresso 和 uiautomator 的测试更加简单。这包括用于重置应用程序数据的工具。 https://github.com/nenick/espresso-macchiato 例如,请参阅 EspAppDataTool 以及清除首选项、数据库、缓存文件和存储文件的方法。
改进@nenick 的解决方案,将状态清除行为封装在自定义 ActivityTestRule
中。如果这样做,您可以允许测试继续自动启动 activity 而无需您的干预。对于自定义 ActivityTestRule
,activity 在启动测试时已经处于所需状态。
规则特别有用,因为它们不依赖于任何特定测试 class,因此可以在任何测试 class 或任何项目中轻松重复使用。
下面是我实施的一个,以确保在每个测试 activity 启动时应用程序已注销。一些测试在失败时会使应用程序处于登录状态。这会导致后面的测试也失败,因为后面的测试假设他们需要登录,但应用程序已经登录了。
public class SignedOutActivityTestRule<T extends Activity> extends ActivityTestRule<T> {
public SignedOutActivityTestRule(Class<T> activityClass) {
super(activityClass);
}
@Override
protected void beforeActivityLaunched() {
super.beforeActivityLaunched();
InstrumentationRegistry.getTargetContext()
.getSharedPreferences(
Authentication.SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE)
.edit()
.remove(Authentication.KEY_SECRET)
.remove(Authentication.KEY_USER_ID)
.apply();
}
}
您可以尝试将此添加到 gradle:
android {
...
defaultConfig {
...
testInstrumentationRunnerArguments clearPackageData: 'true'
}
}
参考https://developer.android.com/training/testing/junit-runner
要在每次测试后从设备的 CPU 和内存中删除所有共享状态,请使用 clearPackageData 标志。
我的一位 QA 工程师正在支持一个具有相当大的代码库和许多不同的 SharedPreferences 文件的应用程序。前几天他来找我询问如何在测试运行之间重置应用程序状态,就好像它已被卸载-重新安装一样。
Espresso(他正在使用)和 Android 测试框架本身都不支持,所以我不确定该告诉他什么。使用本机方法来清除所有不同的 SharedPreferences 文件将是一个非常脆弱的解决方案。
如何在检测期间重置应用程序状态?
当前的 espresso 不提供任何重置应用程序状态的机制。但是对于每个方面(pref、db、文件、权限)都存在一个解决方案。
一开始你必须避免浓缩咖啡自动启动你的 activity 这样你就有足够的时间重新设置。
@Rule
public ActivityTestRule<Activity> activityTestRule = new ActivityTestRule<>(Activity.class, false, false);
然后用
开始你的 activityactivityTestRule.launchActivity(null)
要重置首选项,您可以使用以下代码段(在开始 activity 之前)
File root = InstrumentationRegistry.getTargetContext().getFilesDir().getParentFile();
String[] sharedPreferencesFileNames = new File(root, "shared_prefs").list();
for (String fileName : sharedPreferencesFileNames) {
InstrumentationRegistry.getTargetContext().getSharedPreferences(fileName.replace(".xml", ""), Context.MODE_PRIVATE).edit().clear().commit();
}
您也可以在启动 activity 后重置首选项。但是 activity 可能已经阅读了首选项。
您的应用程序 class 只启动了一次,并且在您可以重置首选项之前已经启动。
我已经开始编写一个库,它应该使使用 espresso 和 uiautomator 的测试更加简单。这包括用于重置应用程序数据的工具。 https://github.com/nenick/espresso-macchiato 例如,请参阅 EspAppDataTool 以及清除首选项、数据库、缓存文件和存储文件的方法。
改进@nenick 的解决方案,将状态清除行为封装在自定义 ActivityTestRule
中。如果这样做,您可以允许测试继续自动启动 activity 而无需您的干预。对于自定义 ActivityTestRule
,activity 在启动测试时已经处于所需状态。
规则特别有用,因为它们不依赖于任何特定测试 class,因此可以在任何测试 class 或任何项目中轻松重复使用。
下面是我实施的一个,以确保在每个测试 activity 启动时应用程序已注销。一些测试在失败时会使应用程序处于登录状态。这会导致后面的测试也失败,因为后面的测试假设他们需要登录,但应用程序已经登录了。
public class SignedOutActivityTestRule<T extends Activity> extends ActivityTestRule<T> {
public SignedOutActivityTestRule(Class<T> activityClass) {
super(activityClass);
}
@Override
protected void beforeActivityLaunched() {
super.beforeActivityLaunched();
InstrumentationRegistry.getTargetContext()
.getSharedPreferences(
Authentication.SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE)
.edit()
.remove(Authentication.KEY_SECRET)
.remove(Authentication.KEY_USER_ID)
.apply();
}
}
您可以尝试将此添加到 gradle:
android {
...
defaultConfig {
...
testInstrumentationRunnerArguments clearPackageData: 'true'
}
}
参考https://developer.android.com/training/testing/junit-runner
要在每次测试后从设备的 CPU 和内存中删除所有共享状态,请使用 clearPackageData 标志。