web-dev-qa-db-fra.com

Comment lire un fichier de test uniquement dans Android test unitaire

Pour mon Android Android, j'écris des tests unitaires qui nécessitent la lecture de certains fichiers. Comme il s'agit de fichiers de test uniquement, je ne les veux pas dans mes dossiers res comme je le fais ne veux pas qu'ils finissent dans ma finale .apk fichier.

Je veux faire quelque chose de similaire à cette question mais en utilisant le nouveau (dans Gradle 1.1) support de test unitaire (par opposition au test d'instrumentation).

La structure de mon projet est la suivante:

/app
   /src
      /main
         /Java/my.module/myClass.Java
         /res/production_resources_go_here
      /test
         /Java/my.module/myClassTest.Java
         /resources/testFile.txt

à quoi devrait ressembler mon test myClassTest pour pouvoir lire avec succès le testFile.txt?

25
Krzysztof Kozmic

Au moment où cette question a été posée, cela ne fonctionnait tout simplement pas. Heureusement, cela a été corrigé depuis.

Vous devez placer votre fichier texte sous le app/src/test/resources dossier comme l'OP tentait de le faire. De plus, il doit être dans le même package que votre classe de test. Donc, si vous avez ReadFileTest.Java dans le package com.example.test dans app/src/test/Java, votre fichier de test doit se trouver dans app/src/test/resources/com/example/test.

test folder structure

Ensuite, vous pouvez accéder à votre fichier texte comme ceci:

getClass().getResourceAsStream("testFile.txt")

Cela ouvre un InputStream pour le fichier texte. Si vous ne savez pas quoi en faire, voici quelques-unes des nombreuses façons dont vous pouvez l'utiliser: Lire/convertir un InputStream en une chaîne

48
Marcin Koziński

Ajoutez ceci à votre build.gradle:

Android {
    sourceSets {
        test {
           resources.srcDirs += ['src/test/resources']
        }
        androidTest {
           resources.srcDirs += ['src/androidTest/resources']
        }
    }
}

Pour que les ressources soient accessibles par des tests unitaires, ajoutez vos fichiers dans: src/test/resources. Et pour les tests d'instrumentation, ajoutez vos fichiers dans: src/androidTest/resources.

10
Deepanshu

Suivi par la réponse de @ Deepansu, j'ai unifié les données de test pour Test et AndroidTest dans {project root}/sampledata répertoire qui est un emplacement par défaut de Android Studio New > Sample Data Directory commande.

1. Dans votre projet, faites un clic droit et cliquez sur New > Sample Data Directory. Cela créera le répertoire sampledata dans app, qui a la même hiérarchie que build.gradle fichier, src et build répertoires.

2. Dans build.gradle, ajoutez des scripts comme ci-dessous;

Android {
    sourceSets {
        test {
           resources.srcDirs += ['sampledata']
        }
        androidTest {
           resources.srcDirs += ['sampledata']
        }
    }
}

.Sync en gradle.

Maintenant, nous pouvons mettre les fichiers de ressources de test dans un répertoire et les utiliser dans les deux environnements de test.

Vous pouvez lire le fichier comme ci-dessous;

// use somewhere at test logic. Note that slash symbol is required (or not).
jsonObject = new JSONObject(readFromFile("/testFile.json"));

// a method to read text file.
public String readFromFile(String filename) throws IOException {
    InputStream is = getClass().getResourceAsStream(filename);
    StringBuilder stringBuilder = new StringBuilder();
    int i;
    byte[] b = new byte[4096];
    while ((i = is.read(b)) != -1) {
        stringBuilder.append(new String(b, 0, i));
    }
    return stringBuilder.toString();
}
7
Youngjae

Je travaille un projet avec une structure similaire à ce que vous avez mentionné. Je place toutes mes réponses de serveur dans un fichier sous le dossier resources comme app/src/test/resources/BookingInfo.json.

Tous les fichiers de test Java sont sous app/src/test/Java/PACKAGE_NAME similaire à ce que vous avez dit. J'ai une classe Fixture sous un package qui contient le nom des ressources:

@SuppressWarnings("nls")
public final class Fixtures
{
    public static final String GET_ANNOUNCEMENT = "GetAnnouncement.json";
...
}

Et enfin une classe FixtureUtils qu'une méthode de cette classe est chargée de lire le fichier de ressources et de retourner le résultat.

import Java.nio.file.Files;
import Java.nio.file.Paths;

public class FixtureUtils
    {
        public static final AFixture fixtureFromName(final String fixtureName)
        {
            final String fixtureString = FixtureUtils.stringFromAsset(fixtureName);

            if (StringUtils.isEmpty(fixtureString))
            {
                return null;
            }

            final Gson gson = new Gson();
            final AFixture aFixture = gson.fromJson(fixtureString, AFixture.class);
            return aFixture;
        }

        private static final String stringFromAsset(final String filename)
        {
            try
            {
                final URL resourceURL = ClassLoader.getSystemResource(filename);
                if (resourceURL == null)
                {
                    return null;
                }

                final String result = new String(Files.readAllBytes(Paths.get(resourceURL.toURI())),
                                Charset.forName("UTF-8")); //$NON-NLS-1$
                return result;
            }
            catch (final Exception e)
            {
                e.printStackTrace();
            }

            return null;
        }

        private FixtureUtils()
        {
            // Ensure Singleton
        }
    }

Et la classe AFixture ressemble à:

public class AFixture
{
    public List<JsonElement> validItems;
    public List<JsonElement> invalidItems;

    public AFixture()
    {
        super();
    }

    public List<JsonElement> getInvalidItems()
    {
        return this.invalidItems;
    }

    public List<JsonElement> getValidItems()
    {
        return this.validItems;
    }

    public void setInvalidItems(final List<JsonElement> invalidItems)
    {
        this.invalidItems = invalidItems;
    }

    public void setValidItems(final List<JsonElement> validItems)
    {
        this.validItems = validItems;
    }

}

Remarque : Java.nio.file a été supprimé de JDK8 si je ne me trompe pas, mais vous n'avez aucun problème si vous utilisez JDK7. Si vous utilisez JDK8, il vous suffit de changer la méthode stringFromAsset d'une manière telle que FileInputStream (style ancien) ou Scanner .

1
Hesam