21

I have setup an android test project that runs junit tests. It's using two eclipse projects "Application" and "ApplicationTest" where my tests are in the "ApplicationTest" project. In one of my tests I need to access a file, this works fine if I put the file on the sdcard and point a File object to it. However I would like to access the file as a resource, but that does not seem to work. This is what I did:

  • Saved the file in ApplicationTest/res/raw/myfile.xml
  • Trying to get it using: InputStream is = getContext().getResources().openRawResource(R.raw.myfile);

But that gives me this exception:

android.content.res.Resources$NotFoundException: File Hello World, HelloAndroidActivity! from drawable resource ID #0x7f040000
at android.content.res.Resources.openRawResource(Resources.java:823)
at android.content.res.Resources.openRawResource(Resources.java:799)
at com.quizzer.test.QuestionHandlerTests.testImportQuestions(Tests.java:182)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:529)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1448)
Caused by: java.io.FileNotFoundException: Hello World, HelloAndroidActivity!
at android.content.res.AssetManager.openNonAssetNative(Native Method)
at android.content.res.AssetManager.openNonAsset(AssetManager.java:406)
at android.content.res.Resources.openRawResource(Resources.java:820)
... 14 more

My test class extends AndroidTestCase so that's where the context comes from.

Update:

So the problem seem to be that during compilation the resources in the test project are used, but at runtime the resources in the main project are used. I am yet unsure how to fix that. So currently it only works if I put the same raw resource both in the test project and the main project which of course is quite stupid.

Zitrax
  • 19,036
  • 20
  • 88
  • 110
  • Its not clear what you are trying to do here. Or may be its just me. Can you elaborate what you are trying to do here. The setup is clear, just give a example of what you expect for a PASS result and a FAIL result. – Siddharth Feb 12 '12 at 15:25
  • @Siddharth I am not sure what I should elaborate on, I mean if the resource was found my test would pass (as it works fine if I access the file directly from the sdcard). I guess I might have missed something about how to use resource files in android, or how to access them from unit test classes. – Zitrax Feb 12 '12 at 15:39
  • So will it help if the android test project is a sub project ? Or a dependent project ? – Siddharth Feb 12 '12 at 16:38

4 Answers4

24

I would suggest extending ActivityTestCase instead of AndroidTestCase. You can than access test project resources via

getInstrumentation().getContext().getResources().openRawResource(R.raw.your_res).

Dummy test case example:

public class Test extends ActivityTestCase {

   public void testFoo() {  

      // .. test project environment
      Context testContext = getInstrumentation().getContext();
      Resources testRes = testContext.getResources();
      InputStream ts = testRes.openRawResource(R.raw.your_res);

      assertNotNull(testRes);
   }    
}

And then in test methods use getInstrumentation().getTargetContext() wherever you used getContext() in your AndroidTestCase extension.

plesatejvlk
  • 427
  • 6
  • 15
  • Thanks this worked. I did get an issue with creating the database though, but found the soltution to it here: http://stackoverflow.com/a/8488722/11722 – Zitrax Mar 22 '12 at 19:15
  • 1
    Thank you so much for the suggestion! P.S. InstrumentationTestCase also seems to work. – Y2i Jul 13 '13 at 12:04
  • 2
    ```getTargetContext()``` did the trick! Thks for pointing it out. – Thuy Trinh Nov 27 '13 at 10:56
  • If you aren't testing an `Activity` but need access to `Instrumentation`, I would recommend extending `InstrumentationTestCase` instead of `ActivityTestCase`. – spaaarky21 Apr 26 '16 at 02:02
  • @plesatejvlk Can i use this in normal Junit test or should i need to move to Instrumentation testing to use this? I am getting an error "android.test.InstrumentationTestCase not mocked" desprite that i have called PowerMockito.mockstatic for InstrumentationTestcase class. – Ajith M A Sep 22 '16 at 08:48
3

I derived the test case as follows:

class MyTest extends InstrumentationTestCase {
    void setUp() {
        InputStream is = getInstrumentation().getContext().getAssets()
            .open("test_image.bmp");
        ...
   }
}

And the file test_image.bmp is saved in assets directory, which is reasonable if you intend to use the asset for some testing related work - and its not part of ui resources. The technique is used in another context here: https://stackoverflow.com/a/4570206/1577626

Community
  • 1
  • 1
vpathak
  • 1,133
  • 12
  • 12
1

With build tools 3.0.0 you can use ActivityTestRule

@RunWith(AndroidJUnit4::class)
@SmallTest
class MainActivityTest {
    @Rule
    @JvmField
    var mainActivityRule = ActivityTestRule(MainActivity::class.java)

    private val baseUrl: String
        get() {
            return mainActivityRule.activity.getString(R.string.base_url)
        }

    @Test
    fun launchingWithMovieIntent() {
            assert.that(baseUrl, equalTo("someValue")
        }
    }
}
Calin
  • 6,661
  • 7
  • 49
  • 80
0

Since Android Gradle Plugin version 1.1 you haven't to use Instrumentation to load file resource.

I wrote here how to do it with POJO unit test case.

Community
  • 1
  • 1
klimat
  • 24,711
  • 7
  • 63
  • 70