web-dev-qa-db-ja.com

Android St​​udio単体テスト:データ(入力)ファイルの読み取り

単体テストで、パスをハードコーディングせずに、(デスクトップ)ファイルシステム上のjsonファイルからデータを読み取るにはどうすればよいですか?

静的な文字列を作成する代わりに、ファイルからテスト入力(解析メソッド用)を読み取りたいです。

ファイルはユニットテストコードと同じ場所にありますが、必要に応じてプロジェクト内の別の場所に配置することもできます。 Android St​​udioを使用しています。

88
Frank

Android-gradle-pluginバージョンに応じて:

1。バージョン1.5以降:

Jsonファイルをsrc/test/resources/test.jsonに置き、次のように参照するだけです。

classLoader.getResource("test.json"). 

段階的な変更は必要ありません。

2。 1.5より下のバージョン:(または何らかの理由で上記の解決策が機能しない場合)

  1. 少なくとも Android Gradleプラグインバージョン1.1 を使用していることを確認してください。リンクに従ってAndroid St​​udioを正しくセットアップしてください。

  2. testディレクトリを作成します。単体テストクラスをJavaディレクトリに配置し、リソースファイルをresディレクトリに配置します。 Android St​​udioは、次のようにマークする必要があります。

    enter image description here

  3. gradleタスクを作成して、リソースをクラスディレクトリにコピーし、classloaderで表示できるようにします。

    Android{
       ...
    }
    
    task copyResDirectoryToClasses(type: Copy){
        from "${projectDir}/src/test/res"
        into "${buildDir}/intermediates/classes/test/debug/res"
    }
    
    assembleDebug.dependsOn(copyResDirectoryToClasses)
    
  4. これで、このメソッドを使用して、ファイルリソースのFile参照を取得できます。

    private static File getFileFromPath(Object obj, String fileName) {
        ClassLoader classLoader = obj.getClass().getClassLoader();
        URL resource = classLoader.getResource(fileName);
        return new File(resource.getPath());
    }
    
    @Test
    public void fileObjectShouldNotBeNull() throws Exception {
        File file = getFileFromPath(this, "res/test.json");
        assertThat(file, notNullValue());
    }
    
  5. ユニットテストを実行する Ctrl+Shift+F10 クラス全体または特定のテストメソッド。
133
klimat

ローカルユニットテスト(対インスツルメンテーションテスト)の場合、ファイルをsrc/test/resourcesの下に置き、classLoaderを使用してそれらを読み取ることができます。たとえば、次のコードは、resourcesディレクトリのmyFile.txtファイルを開きます。

InputStream in = this.getClass().getClassLoader().getResourceAsStream("myFile.txt");

と働いた

  • Android Studio 1.5.1
  • gradleプラグイン1.3.1
67
user3113045

私の場合、解決策はgradleファイルに追加することでした

sourceSets {
    test.resources.srcDirs += 'src/unitTests/resources'
  } 

その後、AS 2.3.1ですべてが見つかりました

javaClass.classLoader.getResourceAsStream("countries.txt")
12
ar-g

Android St​​udioのテストリソースには多くの問題があるため、明確にするためにいくつかのテストを設定しました。 mobile(Android Application)プロジェクトに次のファイルを追加しました。

mobile/src/test/Java/test/ResourceTest.Java
mobile/src/test/resources/test.txt
mobile/src/test/resources/test/samePackage.txt

テストクラス(すべてのテストに合格):

assertTrue(getClass().getResource("test.txt") == null);
assertTrue(getClass().getResource("/test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getResource("samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getResource("/test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getClassLoader().getResource("test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getClassLoader().getResource("test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));

同じルートプロジェクトにJava(Androidではない)プロジェクトdataという名前があります。同じファイルをデータプロジェクトに追加する場合:

data/src/test/Java/test/ResourceTest.Java
data/src/test/resources/test.txt
data/src/test/resources/test/samePackage.txt

その後、Android St​​udioから実行すると、上記のすべてのテストは失敗しますが、./gradlew data:testを使用してコマンドラインを渡します。それを回避するには、このハックを使用します(Groovyで)

def resource(String path) {
    getClass().getResource(path) ?:
            // Hack to load test resources when executing tests from Android Studio
            new File(getClass().getClassLoader().getResource('.').path
                    .replace('/build/classes/test/', "/build/resources/test$path"))
}

使用法:resource('/test.txt')

Android Studio 2.3、Gradle 3.3

8
Love

[実行]-> [構成の編集]-> [JUnit]に移動し、単体テストの実行構成を選択すると、「作業ディレクトリ」設定があります。それはあなたのjsonファイルがある場所を指しているはずです。これにより、他のテストが中断される可能性があることに注意してください。

6
Tas Morf

調査結果をここに追加する必要があります。私はこれが少し古いことを知っていますが、新しいバージョンのGradleではsrc/test/resourcesディレクトリはありませんが、プロジェクト全体で1つのresourcesディレクトリしかありませんので、この行をGradleファイルに追加する必要があります。

Android {
   testOptions {
      unitTests {
         includeAndroidResources = true
      }
    }
}

これにより、次の方法でリソースにアクセスできます。

 this.getClass().getClassLoader().getResourceAsStream(fileName);

私はこれを探していて、答えを見つけることができなかったので、ここで他の人を助けることにしました。

1
Raphael Ayres