如何为android单元测试提供数据文件

时间:2012-03-27 22:28:45

标签: android xml unit-testing junit3

我正在开发使用Android的java.xml.parsers.DocumentBuilder和DocumentBuilderFactory实现从XML文件加载信息的软件。我正在编写我的对象的单元测试,我需要能够提供各种xml文件来运行测试中的代码。我正在使用Eclipse并拥有一个单独的Android测试项目。我找不到将测试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());
  }

3 个答案:

答案 0 :(得分:68)

选项1 :使用InstrumentationTestCase

假设您在android项目和测试项目中都有资源文件夹,并将XML文件放在assets文件夹中。在测试项目下的测试代码中,这将从android项目资产文件夹中加载xml:

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

这将从测试项目资产文件夹中加载xml:

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

选项2 :使用ClassLoader

在测试项目中,如果assets文件夹被添加到项目构建路径(在版本r14之前由ADT插件自动完成),则可以从res或assets目录(即项目构建路径下的目录)加载文件而不使用Context :

String file = "assets/sample.xml";
InputStream in = this.getClass().getClassLoader().getResourceAsStream(file);

答案 1 :(得分:8)

对于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/"

答案 2 :(得分:0)

试试Kotlin:

val json = File("src\\main\\assets\\alphabets\\alphabets.json").bufferedReader().use { it.readText() }