Как предоставить файлы данных для юнит-тестов Android - PullRequest
47 голосов
/ 28 марта 2012

Я занимаюсь разработкой программного обеспечения, которое загружает информацию из файлов XML с использованием реализации Android java.xml.parsers.DocumentBuilder и DocumentBuilderFactory. Я пишу модульные тесты своих объектов, и мне нужно предоставить множество XML-файлов, которые будут проверять тестируемый код. Я использую Eclipse и у меня есть отдельный Android Test Project. Я не могу найти способ поместить тестовый XML в тестовый проект так, чтобы тестируемый код мог открывать файлы.

  • Если я поместил файлы в / assets тестового проекта, тестируемый код не сможет его увидеть.
  • Если я помещаю файлы в / assets тестируемого кода, он, конечно, может видеть файлы, но теперь я загромождаю свою реальную систему тестовыми файлами данных.
  • Если я вручную копирую файлы в каталог / sdcard / data, я могу открыть их из тестируемого кода, но это мешает автоматизации моих тестов.

Будем весьма благодарны за любые предложения о том, как разместить различные тестовые файлы XML в тестовом пакете, но чтобы они были видны тестируемому коду.

Вот как я пытался структурировать юнит-тест:

public class AppDescLoaderTest extends AndroidTestCase
{
  private static final String SAMPLE_XML = "sample.xml";

  private AppDescLoader       m_appDescLoader;
  private Application         m_app;

  protected void setUp() throws Exception
  {
    super.setUp();
    m_app = new Application();
    //call to system under test to load m_app using
    //a sample xml file
    m_appDescLoader = new AppDescLoader(m_app, SAMPLE_XML, getContext());
  }

  public void testLoad_ShouldPopulateDocument() throws Exception
  {
    m_appDescLoader.load();

  }    
}

Это не сработало, поскольку файл SAMPLE_XML находится в контексте теста, но AndroidTestCase предоставляет контекст для тестируемой системы, который не может видеть актив из тестового пакета.

Это модифицированный код, который работал для каждого ответа:

public class AppDescLoaderTest extends InstrumentationTestCase
{
   ...
  protected void setUp() throws Exception
  {
    super.setUp();
    m_app = new Application();
    //call to system under test to load m_app using
    //a sample xml file
     m_appDescLoader = new AppDescLoader(m_app, SAMPLE_XML, getInstrumentation().getContext());
  }

Ответы [ 2 ]

68 голосов
/ 28 марта 2012

Опция 1 : Использовать InstrumentationTestCase

Предположим, у вас есть папка ресурсов как в Android-проекте, так и в тестовом проекте, и вы поместили файл XML в папку ресурсов.в тестовом коде тестируемого проекта это будет загружать XML из папки ресурсов проекта Android:

getInstrumentation().getTargetContext().getResources().getAssets().open(testFile);

Это будет загружать XML из папки активов тестового проекта:

getInstrumentation().getContext().getResources().getAssets().open(testFile);

Вариант 2 : используйте ClassLoader

Если в вашем тестовом проекте папка ресурсов добавляется в путь сборки проекта (что было автоматически выполнено плагином ADT до версии r14), выможно загрузить файл из каталога res или assets (то есть каталогов по пути сборки проекта) без Context:

String file = "assets/sample.xml";
InputStream in = this.getClass().getClassLoader().getResourceAsStream(file);
8 голосов
/ 10 октября 2015

Для модульных тестов Android и JVM я использую следующее:

public final class DataStub {
    private static final String BASE_PATH = resolveBasePath(); // e.g. "./mymodule/src/test/resources/";

    private static String resolveBasePath() {
        final String path = "./mymodule/src/test/resources/";
        if (Arrays.asList(new File("./").list()).contains("mymodule")) {
            return path; // version for call unit tests from Android Studio
        }
        return "../" + path; // version for call unit tests from terminal './gradlew test'
    }

    private DataStub() {
        //no instances
    }

    /**
     * Reads file content and returns string.
     * @throws IOException
     */
    public static String readFile(@Nonnull final String path) throws IOException {
        final StringBuilder sb = new StringBuilder();
        String strLine;
        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"))) {
            while ((strLine = reader.readLine()) != null) {
                sb.append(strLine);
            }
        } catch (final IOException ignore) {
            //ignore
        }
        return sb.toString();
    }
}

Все необработанные файлы я помещаю по следующему пути: ".../project_root/mymodule/src/test/resources/"

...