web-dev-qa-db-ja.com

Android単体テストのデータファイルを提供する方法

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());
  }
47

オプション1InstrumentationTestCase を使用

Androidプロジェクトとテストプロジェクトの両方にアセットフォルダーがあり、XMLファイルをアセットフォルダーに配置したとします。テストプロジェクトのテストコードでは、これによりAndroidプロジェクトアセットフォルダーからxmlがロードされます。

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

これにより、テストプロジェクトのアセットフォルダーからxmlがロードされます。

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

オプション2ClassLoader を使用

テストプロジェクトで、アセットフォルダーがプロジェクトビルドパス(バージョンr14より前のADTプラグインによって自動的に行われた)に追加された場合、コンテキストなしでresまたはassetディレクトリ(つまり、プロジェクトビルドパスの下のディレクトリ)からファイルをロードできます:

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

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

8
ultraon