mirror of
https://github.com/MinimalBible/MinimalBible.github.io
synced 2024-12-21 22:28:17 -05:00
Add a post on Robolectric w/ SDK 21
This commit is contained in:
parent
70817c75e9
commit
aa5489bd89
147
_posts/2015-02-23-robolectric-plus-android-lollipop.md
Normal file
147
_posts/2015-02-23-robolectric-plus-android-lollipop.md
Normal file
@ -0,0 +1,147 @@
|
||||
---
|
||||
layout: post
|
||||
title: "Robolectric + Android Lollipop"
|
||||
modified: 2015-02-23 00:29:49 -0500
|
||||
tags: [robolectric,lollipop,sdk21,testing,coverage]
|
||||
image:
|
||||
feature:
|
||||
credit:
|
||||
creditlink:
|
||||
comments:
|
||||
share:
|
||||
---
|
||||
|
||||
Getting actual Android code running on your computer
|
||||
----------------------------------------------------
|
||||
|
||||
So far in the life of [MinimalBible](0) the
|
||||
whole testing situation has been... *eherm*... convoluted. I've previously outlined why
|
||||
I [replatformed](1) the application, how managing the `Application` lifecycle [makes testing
|
||||
difficult](2), and finally how I've gotten [non-emulator testing set up](3) to report code coverage.
|
||||
|
||||
One of the things I've wanted to do for a while, but proved difficult after many long nights with
|
||||
StackOverflow and other technology sites was get the [Robolectric](4) project working with my code.
|
||||
Robolectric is basically a re-implementation of the Android SDK designed for easy testing. So instead
|
||||
of having to run Android tests on an actual device, you can skip that.
|
||||
|
||||
Quick caveat: [Don't write UI tests using Robolectric](5). Robolectric is great for running small tests
|
||||
that have to use Android API's, but should not be used to validate that your UI code is working. You won't
|
||||
have an emulator or other device to make sure you actually wrote the tests the right way.
|
||||
|
||||
And with that out of the way, let me get into what it took for me to get Robolectric up and running for MinimalBible.
|
||||
I imagine there will be other people with similar issues, so it's good to go ahead and talk about. All the code
|
||||
this post is based off of can be found at commit [71fb362ffe](6).
|
||||
|
||||
Assuming you have the project set up as discussed [in my previous post](3) (which was inspired by [this](7)),
|
||||
the `build.gradle` file change is pretty simple. Just add the following dependency:
|
||||
|
||||
```groovy
|
||||
|
||||
dependencies {
|
||||
testCompile 'org.robolectric:robolectric:2.+'
|
||||
}
|
||||
```
|
||||
|
||||
We need to add a special file called `project.properties` to the `<app_name>/src/main` folder with this content:
|
||||
|
||||
```
|
||||
|
||||
# suppress inspection "UnusedProperty" for whole file
|
||||
android.library.reference.1=../../build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.3
|
||||
android.library.reference.2=../../build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3
|
||||
|
||||
```
|
||||
|
||||
The "suppress" line at the top is so that Android Studio doesn't warn you that the properties are unused.
|
||||
|
||||
The `Activity` we're actually going to be testing is pretty simple too ([code here](8)):
|
||||
|
||||
```java
|
||||
|
||||
public class BasicSearch extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_search_results);
|
||||
|
||||
handleSearch(getIntent());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
So now that the `Activity` is set up, we need to build a simple test case. Let's do something like this ([code here](9)):
|
||||
|
||||
```java
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(emulateSdk = 18, manifest = "../app/src/main/AndroidManifest.xml")
|
||||
public class BasicSearchTest {
|
||||
@Test
|
||||
public void testBuildActivity() {
|
||||
BasicSearch activity = Robolectric.buildActivity(BasicSearch.class)
|
||||
.create().get();
|
||||
assertNotNull(activity);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This test is just responsible for getting the `Activity` started, and will fail if there are any issues during startup.
|
||||
Please note that this also includes the `Application` getting started as well,
|
||||
so it may throw off your coverage metrics.
|
||||
|
||||
By any means, we're now done with the hardest part. With any luck, the test will run, and you'll get a nice green bar
|
||||
telling you that the test was successful.
|
||||
|
||||
There's one quick caveat: **When you run tests with Gradle, all tests are run in the application test project folder.**
|
||||
In my case, that's the `app-test` folder. This is important, because **Android Studio by default likes to run tests
|
||||
in the project root directory instead**. So if the tests work with Android Studio, and not with Gradle,
|
||||
that's likely the issue.
|
||||
|
||||
**But** if it was actually that easy, it wouldn't be worth yet another post.
|
||||
|
||||
Robolectric + AppCompat - The deadly duo
|
||||
----------------------------------------
|
||||
|
||||
As of right now, Robolectric has very limited support for Android Lollipop (SDK 21), and most specifically the
|
||||
`appcompat` libraries it ships with. Unfortunately it appears that the `ActionBarDrawerToggle` is causing some
|
||||
[rather hairy problems](10) that aren't easy to figure out.
|
||||
|
||||
So if you're trying to get Robolectric working on a Lollipop app, here are my tips from the school of hard knocks:
|
||||
|
||||
1. You can only test Activities that do not use the `ActionBarDrawerToggle`. This thankfully means that `Fragment`
|
||||
testing will work just fine if you set them up maybe outside the original intended `Activity`.
|
||||
|
||||
2. Please make sure that all tests receive an `@Config(emulateSdk = 18)` until [this issue](11) is closed.
|
||||
|
||||
3. Please make sure that Robolectric picks up the support libraries when testing. If they are noticed correctly,
|
||||
the test will output text which includes the two lines below:
|
||||
|
||||
{% highlight text %}
|
||||
DEBUG: Loading resources for android.support.v7.appcompat from ./../app/src/main/../../build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.3/res...
|
||||
DEBUG: Loading resources for android.support.v4 from ./../app/src/main/../../build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/res...
|
||||
{% endhighlight %}
|
||||
|
||||
And at this point if you've followed all the tips, you should be good to go!
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
So now that we've gone over how to get Robolectric working, and some of the tricks you need to get it working in
|
||||
Lollipop, go forward and write tests. Who knows, it might bump up your coverage metrics [11%](12).
|
||||
|
||||
Comment below if you have any questions, I'll do what I can to help!
|
||||
|
||||
[0]: https://github.com/MinimalBible/MinimalBible
|
||||
[1]: http://minimalbible.github.io//replatform-retrospective/
|
||||
[2]: http://minimalbible.github.io//testing-with-dagger/
|
||||
[3]: http://minimalbible.github.io//android-and-jacoco/
|
||||
[4]: http://robolectric.org/
|
||||
[5]: https://github.com/futurice/android-best-practices#use-robolectric-for-unit-tests-robotium-for-connected-ui-tests
|
||||
[6]: https://github.com/MinimalBible/MinimalBible/commit/71fb362ffea4d7c7abfc8a7615e7db216be50e4e
|
||||
[7]: http://blog.blundell-apps.com/android-gradle-app-with-jvm-junit-tests/
|
||||
[8]: https://github.com/MinimalBible/MinimalBible/blob/71fb362ffea4d7c7abfc8a7615e7db216be50e4e/app/src/main/java/org/bspeice/minimalbible/activity/search/BasicSearch.java
|
||||
[9]: https://github.com/MinimalBible/MinimalBible/blob/71fb362ffea4d7c7abfc8a7615e7db216be50e4e/app-test/src/test/java/org/bspeice/minimalbible/activity/search/BasicSearchTest.java
|
||||
[10]: https://github.com/robolectric/robolectric/issues/1424
|
||||
[11]: https://github.com/robolectric/robolectric/issues/1446
|
||||
[12]: https://coveralls.io/builds/1946159
|
Loading…
Reference in New Issue
Block a user