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:
- IntelliJ
- Maven multi-module project:
- Parent-pom
- Android Application
- Android Test Project to test the Android Application
- Unit tests using the following frameworks
- Mockito for mocking
- Robolectric
- 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
- Create an empty directory under the project root called res (if doesn't already exist)
- 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.