Posted:

android junit testing of libGDX applications

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 ...

Comments or Questions?

Subscribe via RSS | Atom Feed