Posted: 16 April 2012
The Android Development Tools have special support for JUnit testing of Android apps. These let you run unit tests against your Android app deployed on an AVD or physical device. (As opposed to the simpler JUnit white-box tests that just run your code on your desktop, without exercising Android specific code.)
However, because I'm building my Android app with libGDX this required a bit of extra work to integrate. I'll go over the steps I took to get Android JUnit testing running. But first, a short review of basic JUnit configuration.
Simple JUnit
Simple JUnit tests that do not rely on Android or libGDX functions can be run on a libGDX-based application, using the standard JUnit infrastructure. For example, in my base application package, I have a test directory that contains simple JUnit tests, and I can run them directly from that package (i.e., not the "desktop" or "android" packages of my app.) Existing JUnit tutorials, like this excellent one from Lars Vogel will help you get started.
I'd recommend getting some of these tests working before trying the full app tests.
Full App JUnit
The Android docs on this topic cover the details, but I found the organization somewhat confusing and I had to jump back and forth between the guide and the tutorial to make everything work.
First, follow the initial steps outlined in the Android Dev Guide to create a new Android Test Project. This will implicitly create a new android application project. This project, when built and run on an Android device or Android emulator, will run tests (and only indirectly run your application). Tests can interact with your application's UI, or just run whitebox tests that have no UI.
To make this work with libGDX, you may need to configure the libraries that
are "exported" from your Android project. Right-click on your Android app
and select Build Path -> Configure Build Path...
. Select the Order and
Export
tab. Make sure the gdx
and common
project are checked (this tags
those libraries as "exports" of this project so the Android Test App can see
them). Frankly, I'm not 100% sure of which ones are strictly required,
but can't see any harm from exporting too much...
At this point you should have a test app that would build if it contained anything.
Switch over to the Android tutorial to
create a new test class
in your new test project. I uninspiringly named my class GameTest
. I
made it a subclass of
android.test.ActivityInstrumentationTestCase2<AndroidGame>
.
Note the 2
in the class name, and the type parameter. You'll need to provide the name of the main
class of your Android activity (the one that extends
com.badlogic.gdx.backends.android.AndroidApplication
, overrides
onCreate
and invokes initialize
), in my case that is the equally
uninspiring AndroidGame
.
The first step to making your test case useful is to be able to peel
through the onion to get at your game's classes. The getActivity()
method defined by AndroidInstrumentationTestCase2
will fetch the current
activity and will start it up if necessary.
Here is a lame test case that will demonstrate that you've got the right bits connected up:
public void testType() { AndroidApplication gdxApp = (AndroidApplication)this.getActivity(); assertEquals(gdxApp.getType(), ApplicationType.Android); }
Try running this (right click on your test game class and choose Run
As... -> JUnit Android Test
.
There are more details on defining a test case class in the tutorial.
There are several more hurdles to making useful tests, though. The first
is that libGDX isn't particularly built for inspection, for example, there
is no getListener()
method on AndroidApplication
to get the listener
that probably contains all your game's interesting state. This is easy
enough to work-around by implementing your own lookup methods, though.
The next hurdle is to actually build tests. You'll need more help from your game to interact with, and more importantly, wait on, the app instance being tested. Perhaps a later post will cover that ...