JUnit testing of libGDX game in Android Studio

Bringing JUnit4 into Android Studio to test your libGDX game

On first thought I assumed it would be a trivial endeavor to set up JUnit tests in Android Studio for libGDX-based game projects. But surprisingly enough, it turned out to be more challenging to say the least.

And the good news is that after a long, hard search through several articles, forums, and the Android Developer and Gradle websites, I came up with a simple procedure that worked well for me. Hopefully this will also help you avoid the time and effort I went through doing the research and working through the issues.

NOTE: This article is based on JUnit4 and Android Studio 2.1.2 (latest version at the time of this article) running on a Windows machine.

Procedure

  1. Generate the libGDX game using the LibGDX Project Generator (gdx-setup.jar).
  2. Import the libGDX project into Android Studio according to one of my earlier articles: Set up libGDX game in Android Studio
  3. Follow the procedure in the “libGDX Core module” section below.
  4. Follow the procedure in the “libGDX Android module” section below that.

libGDX Core module

This procedure is for setting up JUnit4 within Android Studio 2 for unit testing the libGDX ‘core’ module.

Step 1: Set up the JUnit library

Add the JUnit library to the main build.gradle file (in the project root):

build.gradle
   :
allprojects {
       :
      ext {
           :
        junitVersion = '4.12'
    }

project(":core") {
    apply plugin: "java"

    dependencies {
        compile "com.badlogicgames.gdx:gdx:$gdxVersion"
        compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
        testCompile "junit:junit:$junitVersion"
    }
}

Step 2: Set up unit test folder

Since we’re using latest version of Android Studio (2.1.2 at the time of this writing), to get the best results we follow the latest Android developer recommended test folder structure: Test Types and Location. This will separate the unit test classes and any unit test resource files from the production classes and resource files.

So let’s first reorganize the directory structure. The ‘core’ module’s original and new libGDX directory structures are shown in this table:

Original New Description
core/src core/src/main/java Java sources directory
core/src/test/java Java unit test sources directory (where our unit test classes will reside)
core/src/test/res Optional: Unit test resources directory (for resource files that are only used by unit tests)
  1. Create the new directories according to the table above.
  2. Move the content from the old 'core/src' to the new 'core/src/main/java' location.

    NOTE: If you’re using Android Studio’s built-in version control system (VCS), then it should preserve the history of these folder changes for you. Otherwise, don’t forget to move the files in such a way that preserves your change history.

  3. Open the core/build.gradle and replace this line
sourceSets.main.java.srcDirs = [ "src/" ]

…with these lines.

sourceSets.main.java.srcDirs = [ "src/main/java/" ]
sourceSets.test.java.srcDirs = [ "src/test/java/" ]
sourceSets.test.resources.srcDirs = [ "src/test/res/" ]

Note: Include the resources line only if your tests will have their own resource files.

  1. Perform a Gradle project sync (click ‘Sync Now’ link if it automatically shows up in Android Studio).
  2. In the Project view, the 'core/src/test/java' folder should turn green indicating it is properly setup as a test folder recognized by Gradle and Android Studio.

WARNING: The creation of the Java folder might add the new ‘src/test/java/’ test directory as a source file to your build.gradle file’s sourceSets statement. So if you have the following entry in your app/build.gradle file, you need to remove it, since ‘test’ should not be treated as a normal source folder (like ‘main’ is)!

sourceSets { main { java.srcDirs = ['src/main/java', 'src/test/java/'] } }

Step 3: Create a test

    1. Open one of your source files to be tested (e.g. core/src/main/java/<my-package>/Utils.java)
    2. First click on the source file, then bring up the ‘Create Test’ dialog by:
      Ctrl + Shift + T > Create New Test…
    3. Make sure Testing library is set to: JUnit4
    4. Click ‘Fix’ link if it pops up.
    5. Change the Class name if desired.
    6. Leave the Destination package the same as the source file’s.
    7. Select the checkboxes of what to Generate.
    8. OK

Step 4: Edit the test (optional)

The test will pass even if we leave the test method empty. But you may optionally add an Assert statement like in this example unit test method that tests a numerical string conversion to a long:

UtilsTest.java
@Test
public void testGetLong() throws Exception {
    Assert.assertEquals(123L, Utils.getLong("123"));
}

Step 5: Create a JUnit Run/Debug configuration

In order to execute the unit tests, create a JUnit Run/Debug configuration for a package of source files to test.

  1. In Project view, right-click on (green) 'core/src/test/java' folder and choose: Create ‘All Tests’
    Create a JUnit Run-Debug configuration
  2. The dialog pops up: Create Run/Debug Configuration: ‘All in core’
  3. Change the Name if desired.
  4. Click on the Package browse (…) icon and navigate to and select the desired package for this configuration to handle.Create Run-Debug Configuration All in core
  5. Run the new test configuration for the package: Run > Run ‘All in core’
  6. The Run view should open and display the test as passed.Run All in core

Set up libGDX game in Android Studio

A quick tutorial for setting up your libGDX game to run in Android Studio on Windows

First we’ll create a libGDX project, then import it into Android Studio, and finally configure the desktop, Android, and HTML5 modules.

NOTE: These instructions and screenshot(s) are based on a Windows 10 machine running Android Studio 2.1.2.

Create New libGDX Project

  1. Download and install Java SE Development Kit (verify if installed).
  2. Download and install Android Studio (if not installed)
  3. Download the libGDX Setup App (gdx-setup.jar), and run it (by double-clicking on it).libGDX setup app
  4. Enter:
    • Name – enter the display name of your game (spaces are OK).
    • Package – enter the base package for your game (e.g. com.mycompany.mygame).
    • Game class – enter the name of your main game class (e.g. MainGame).
    • Destination – enter your new game folder to hold all its project files (e.g. C:\dev\MyGame).
    • Android SDK – specify location where Android Studio installed it (e.g. On Windows, typically:  C:\Users\YourUsername\AppData\Local\Android\sdk)
  5. Check options for this tutorial, choose Sub Projects: Desktop, Android, and Html.
  6. Click button: Generate
  7. If any dialog pops up, it’s OK to specify newer tool or API versions.

Import into Android Studio

  1. Open Android Studio and choose: File > New > Import Project
  2. Select the project Destination folder specified above.
  3. Give Android Studio time to import, and accept any Gradle Update request dialogs.
  4. Wait for Gradle build to finish.
  5. Create a Run/Debug Configuration for our Desktop version (since most of our development and testing will be in this version).
    1. Select: Run > Edit Configurations…
    2. Click toolbar icon: +
    3. Choose: Application
    4. For ‘Name’, enter: desktop
    5. Under Configuration tab, specify:
      • Use classpath of module – click dropdown arrow and choose: desktop
      • Main class – click browse (…) and choose: DesktopLauncher
      • Working directory – click browse (…) and navigate to ‘android/assets’ folder (e.g. C:\dev\MyGame\android\assets)

        Note: Since we chose the Android module in the libGDX Setup App, libGDX then looks for all its resources in the Android module’s assets folder. All the music, image, and texture files, etc. will need to go in this folder.

    6. Click: OK
    7. Run the Desktop configuration, and the application will pop up with the bad logic logo image on a red background.

Configure libGDX Launcher classes

Your libGDX game is now runnable. However, a few extra tweaks will improve your development and enhance your game.

For all the platform versions chosen in this tutorial for our game, we establish for the graphics, a target resolution of 800 x 480 pixels (landscape aspect ratio) — which is currently typical for an Android mobile device. To achieve this we need to add platform-specific configuration code to the libGDX Launcher classes for the chosen ‘desktop’, ‘android’, and ‘html’ modules.

Desktop module

For the desktop version of our game, we need to specify a 800 x 480 window size, and optionally set the title for the name of our game. For this we modify DesktopLauncher.java like this:

DesktopLauncher.java
package com.mycompany.mygame.desktop;

import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.mycompany.mygame.MainGame;

public class DesktopLauncher {
    public static void main(String[] arg) {
        LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
        config.title = "My Game";
        config.width = 800;
        config.height = 480;
        new LwjglApplication(new MainGame(), config);
    }
}

Android module

This section describes the configurations for the Android version of our game.

AndroidManifest.xml

No changes are necessary since the libGDX Setup App created an AndroidManifest.xml file that already meets the above requirements by defaulting to android:screenOrientation="landscape"

Note: If the game needed to run in portrait mode, we would set this attribute to android:screenOrientation="portrait" and swap the resolution width and height for the desktop and html modules.

Unlike the ‘desktop’ module, we can’t define the resolution of the Activity since it is set by the Android operating system. So instead, our game will need to handle this by scaling the 800 x 480 target resolution to whatever the device’s resolution is.

AndroidLauncher.java

The only changes we need to make to the AndroidLauncher.java file are optional, such as conserving the battery by disabling the accelerometer and the compass like this:

AndroidLauncher.java
package com.mycompany.mygame;

import android.os.Bundle;

import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.mycompany.mygame.MainGame;

public class AndroidLauncher extends AndroidApplication {
	@Override
	protected void onCreate (Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
		config.useAccelerometer = false;
		config.useCompass = false;
		initialize(new MainGame(), config);
	}
}

HTML module

For the HTML5 version of our game, we need to specify a 800 x 480 drawing area. For this we modify the HtmlLauncher.java file like this:

HtmlLauncher.java
package com.mycompany.mygame.client;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.gwt.GwtApplication;
import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;
import com.mycompany.mygame.MainGame;

public class HtmlLauncher extends GwtApplication {
        @Override
        public GwtApplicationConfiguration getConfig () {
	    return new GwtApplicationConfiguration(800, 480);
        }

        @Override
        public ApplicationListener createApplicationListener () {
            return new MainGame();
        }
}

Conclusion

All the libGDX Launcher classes are now correctly configured, so you can move on to implementing your fantastic new game!