web-dev-qa-db-ja.com

InstrumentationTestCaseの実行間でアプリの状態をリセットする

私のQAエンジニアの1人は、かなり大きなコードベースと多くの異なるSharedPreferencesファイルを備えたアプリをサポートしています。彼は先日、アンインストールして再インストールしたかのように、テスト実行の間にアプリケーションの状態をリセットする方法を尋ねてきました。

Espresso(彼が使用している)でも、Androidテストフレームワーク)でもネイティブでサポートされているようには見えないので、何を伝えるべきかわからない。すべての異なるSharedPreferencesファイルは、非常に脆弱なソリューションになります。

インストルメンテーション中にアプリケーションの状態をリセットするにはどうすればよいですか?

18
Turnsole

現在のエスプレッソは、アプリケーションの状態をリセットするメカニズムを提供していません。しかし、それぞれの側面(設定、データベース、ファイル、権限)には解決策があります。

最初は、エスプレッソが自動的にアクティビティを開始するのを避けて、リセットするのに十分な時間を確保する必要があります。

@Rule
public ActivityTestRule<Activity> activityTestRule = new ActivityTestRule<>(Activity.class, false, false);

そして後であなたの活動を始める

activityTestRule.launchActivity(null)

設定をリセットするには、次のスニペットを使用できます(アクティビティを開始する前に)

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();
}

アクティビティを開始した後も、設定をリセットできます。しかし、そのアクティビティはすでに設定を読んでいる可能性があります。

アプリケーションクラスは1回だけ開始され、設定をリセットする前にすでに開始されています。

私は、espressoとuiautomatorを使用してテストをより簡単にするライブラリを作成し始めました。これには、アプリケーションデータをリセットするためのツールが含まれます。 https://github.com/nenick/espresso-macchiato たとえば、環境設定、データベース、キャッシュファイル、および保存されたファイルをクリアするためのメソッドを備えたEspAppDataToolを参照してください。

32
nenick

@nenickのソリューションを改善し、状態クリア動作をカスタムActivityTestRuleにカプセル化します。これを行うと、ユーザーの介入なしに、テストでアクティビティを自動的に起動し続けることができます。カスタムActivityTestRuleを使用すると、アクティビティはテストのために起動されたときにすでに望ましい状態にあります。

ルールは特定のテストクラスに関連付けられていないため特に便利です。ルールは、任意のテストクラスまたはプロジェクト内で簡単に再利用できます。

以下は、アクティビティの起動時にテストごとにアプリがログアウトされるようにするために実装したものです。一部のテストは、失敗したときにアプリをサインイン状態のままにしていました。これにより、後のテストでもサインインが必要であると想定されたため、後のテストも失敗しますが、アプリはすでにサインインされています。

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();
    }

}
9
Julian A.