Monday, 29 April 2013

Robolectric Error - Couldn't find value resource directory


Android development using Robolectric provides a powerful testing framework which runs on your desktop JVM instead of an Android device or emulator. This makes tests written using Robolectric run a lot faster than those written to run using Android Instrumentation.

However, when setting up Robolectric in IntelliJ, I recently received the following nastiness:

testExceptionThrownGivenNullHeadersInput(LocationHeaderParsingTest)  Time elapsed: 28.753 sec  <<< ERROR!
java.lang.RuntimeException: java.lang.RuntimeException: Couldn't find value resource directory: C:\Programming\Workspace\ .... \.\res\values
at com.xtremelabs.robolectric.res.ResourceLoader.getValueResourceDir(ResourceLoader.java:296)
at com.xtremelabs.robolectric.res.ResourceLoader.init(ResourceLoader.java:133)
at com.xtremelabs.robolectric.res.ResourceLoader.setLayoutQualifierSearchPath(ResourceLoader.java:599)
at com.xtremelabs.robolectric.RobolectricTestRunner.setupApplicationState(RobolectricTestRunner.java:367)
at com.xtremelabs.robolectric.RobolectricTestRunner.internalBeforeTest(RobolectricTestRunner.java:311)
at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:278)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:208)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:158)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:86)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:95)

My particular setup is as follows:

  1. IntelliJ
  2. Maven multi-module project:
    1. Parent-pom
      1. Android Application
      2. Android Test Project to test the Android Application
  3. Unit tests using the following frameworks
    1. Mockito for mocking 
    2. Robolectric 
    3. Robotium for auotmated UI testing
The problem here is that when creating my Android Test Project, I didn't see the need to create the res/values directory (as my tests didn't require any resources from here). However, the Robolectric framework does not work properly without that directory being present.

Solution
  1. Create an empty directory under the project root called res (if doesn't already exist)
  2. Create an empty directory in res called values
Your project structure should therefore look something like this:

application-myapp-android-parent
     |
     |-> application-myapp-android
     |-> application-myapp-android-test
               |-> res
                     |->values

That should fix your Couldn't find value resource directory issue.