In the past few days I had a little bit of a problem: InstrumentationTestCase gives access to local assets while AndroidTestCase gives access to getAssets() for assets specific to testing.

I had a scenario to test where I get a file from my local src/androidTest/assets directory while the code would need to write some files in /data/data/my.package.name.test/files directory. Quite unfortunate I'd say.

My solution was to create an InputStream method based on this answer, to cover both cases.

The code is:

private InputStream getAssetStream(Context context, String fileName)
    throws IOException {
    InputStream result;
    try {
        result = context.getResources().getAssets().open(fileName);
    } catch (IOException e) {
        result = this.getClass()
            .getClassLoader()
            .getResourceAsStream("assets" + File.separator + fileName);
    }
    if (result == null)
        throw new IOException(
            String.format("Asset file [%s] not found.",
                fileName)
        );

    return result;
}

This way, if the method is called from an InstrumentationTestCase , the first call will get the right result because, as I've mentioned above, InstrumentationTestCase gives us access to local assets. If called from an AndroidTestCase , the first path will get a FileNotFoundException and the second variant will try to get the file from the class loader. Normally, only the two options can happen; the second one fails only if the classpath is missing the test content (which it shouldn't).