Тестирование модулей Android Studio: чтение данных (ввода)

В unit test, как я могу читать данные из json файла в моей (настольной) файловой системе без жесткого кодирования пути?

Я хотел бы прочитать тестовый ввод (для моих методов синтаксического анализа) из файла вместо создания статических строк.

Файл находится в том же месте, что и код модульного тестирования, но при необходимости я могу разместить его где-то еще в проекте. Я использую Android Studio.

Ответ 1

В зависимости от версии android-gradle-plugin:

1. версия 1.5 и выше:

Просто поместите файл json в src/test/resources/test.json и src/test/resources/test.json его как

classLoader.getResource("test.json"). 

Модификация Gradle не требуется.

2. версия ниже 1.5: (или если по какой-то причине вышеуказанное решение не работает)

  1. Убедитесь, что вы используете как минимум Android Gradle Plugin версии 1.1. Перейдите по ссылке, чтобы правильно настроить Android Studio.

  2. Создать test каталог. Поместите классы модульного теста в каталог java и поместите файл ресурсов в каталог res. Android Studio должна пометить их следующим образом:

    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 для всего класса или конкретного метода тестирования.

Ответ 2

Для локальных тестов (по сравнению с инструментальными тестами) вы можете помещать файлы под src/test/resources и читать их с помощью classLoader. Например, следующий код открывает файл myFile.txt в каталоге ресурсов.

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

Он работал с

  • Android Studio 1.5.1
  • gradle плагин 1.3.1

Ответ 3

В моем случае решение заключалось в добавлении в файл gradle

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

После этого все было найдено AS 2.3.1

javaClass.classLoader.getResourceAsStream("countries.txt")

Ответ 4

У меня было много проблем с тестовыми ресурсами в Android Studio, поэтому я установил несколько тестов для ясности. В моем 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 Studio, но они передают в командной строке ./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

Ответ 5

Если вы перейдете в Run → Edit configuration → JUnit, а затем выберите конфигурацию прогона для своих модульных тестов, появится настройка "Рабочий каталог". Это должно указывать на то, где находится ваш json файл. Имейте в виду, что это может нарушить другие тесты.

Ответ 6

Я хотел бы добавить свои выводы здесь. Я знаю, что это немного устарело, но для более новых версий Gradle, где НЕТ каталога src/test/resources, но только один единственный каталог ресурсов для всего проекта, вы должны добавить эту строку в свой файл Gradle.

android {
   testOptions {
      unitTests {
         includeAndroidResources = true
      }
    }
}

Делая это, вы можете получить доступ к своему ресурсу с:

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

Я искал это и не мог найти ответ, поэтому я решил помочь другим здесь.