Test me – if you can!

Unit Tests mit Android Studio

Lars Röwekamp, Arne Limburg

© Shutterstock.com / Ociacia

Seit der Einführung des Android Studios als offizielle Android-IDE hält sich vehement das Gerücht, dass eine sinnvolle Absicherung der eigenen Sourcen durch Unit Tests nur mit sehr viel Bauchschmerzen und auch nur unter Verwendung der veralteten JUnit-Version 3.x zu realisieren ist. Hatte diese Aussage in der Version 1.0 durchaus noch ihre Berechtigung, gilt spätestens seit der Nachfolgerversion 1.1 das Gegenteil.

Sucht man im Internet nach Quellen zum Thema „Einrichten von Unit Tests im Android Studio“, stößt man unweigerlich auf ausführliche und nicht minder komplizierte Step-by-Step-Anleitungen, die beschreiben, wie Unit Tests im Android Studio trotz angeblich fehlender Unterstützung doch aktiviert werden können. In den meisten Fällen wird man dazu aufgefordert, das build.gradle-Skript um einige Zeilen zu erweitern, diverse Plug-ins zu laden und damit letztendlich die notwendigen Instrumentationstests zu ermöglichen.

Zugegeben, in den frühen Betaversionen des Android Studios war es tatsächlich alles andere als trivial, einen Unit Test zum Laufen zu bekommen. Und auch in der Version 1.0 gab es noch die ein oder andere Hürde, die es zu überwinden galt. Aber spätestens seit der Version 1.1 ist dieses Problem obsolet. Lediglich ein kleines Häkchen unter Enable Unit Test Support in den Gradle Preferences (Experimental) sowie die Verwendung des Gradle-Plug-ins 1.1.0 oder höher und schon können Unit Tests problemlos angelegt und ausgeführt werden. Noch einfacher ist es in der Nachfolgerversion 1.2, in der Unit-Test-Support per Default aktiviert ist.

Wo liegt was?

Android Studio unterscheidet bei Tests zwei Artefaktvarianten, welche gezielt in dem Build-Variantfenster ausgewählt und über eigene Run-Konfigurationen gestartet werden können. Während reine Unit Tests, also Tests, die ohne Unterstützung des Emulators bzw. des Android OS laufen, per Konvention in einem parallel zu src/main liegenden Verzeichnis src/test erwartet werden, sollten Android-Instrumentationstests, also Tests, die direkt oder indirekt auf das Android-Testing-Framework und somit auf den darin enthaltenen Instrumentationsmechanismus zurückgreifen, in dem Verzeichnis src/androidTest abgelegt werden.

JUnit-4-Support

Eine weitere Mär besagt, dass Unit Tests unter Android nur mit der JUnit-Version 3.x möglich sind, was u. a. strikte Namenskonventionen für die Testartefakte, also die Klassen und Methoden, mit sich bringt und die Verwendung von den erst in Version 4 eingeführten JUnit-Annotationen sowie allen weiteren JUnit-4-spezifischen Features verbietet. Auch dies stimmt heute in dieser Form nicht mehr.

Im Rahmen der Android Support Test Library, welche sich im Android Support Repository befindet und innerhalb des Android Studios via SDK Manager heruntergeladen werden kann, stellt Google einen eigenen AndroidJUnitRunner zur Verfügung. Neben der JUnit-Version 3 wird so auch die Version 4 im vollen Umfang unterstützt. Auch eine parallele Verwendung beider Versionen in einer Testsuite ist möglich. Lediglich innerhalb eines Tests sollte eine gemeinsame Nutzung beider API-Versionen vermieden werden, da es sonst zu nicht vorhersehbaren Nebeneffekten kommen kann. Zum Einbinden in das eigene Projekt müssen lediglich die folgenden Einträge in dem build.gradle-Skript ergänzt werden, welche übrigens gleichzeitig auch die Verwendung des Espresso-Test-Frameworks ermöglichen:

// inside dependencies
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
androidTestCompile 'com.android.support.test:runner:0.2'

// inside android.defaultConfig 
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

Möchte man JUnit 4 im direkten Zusammenspiel mit dem API des Android-Testing-Frameworks verwenden, um so zum Beispiel einen JUnit-4-basierten Test zu schreiben, der von der Klasse ActivityInstrumentationTestCase2 ableitet, gilt es, zusätzlich zu den oben genannten Schritten einige Regeln zu beachten:

  • Zunächst muss die eigene Testklasse mit @RunWith(AndroidJUnit4.class) annotiert werden.
  • Zusätzlich muss die setUp()-Methode der Klasse ActivityInstrumentationTestCase2 überschrieben und mit @Before annotiert werden. Innerhalb der Methode muss ein Aufruf von super.setUp() erfolgen.
  • Da durch die Verwendung eines neues Test Runners keine automatische Einbindung der Android-Instrumation erfolgt, muss dies innerhalb der Setup-Methode durch den Aufruf der Methode injectInstrumentation(InstrumentationRegistry.getInstrumentation()) „manuell“ erfolgen.
  • Tests, die durch den Runner ausgeführt werden sollen, müssen mit @Test annotiert werden. Der Name des Tests spielt dabei, im Gegensatz zu JUnit 3, keine Rolle.
  • Abschließend muss noch die tearDown()-Methode der ActivityInstrumentationTestCase2-Klasse überschrieben und mit @After annotiert werden. Innerhalb der Methode muss ein Aufruf von super.tearDown() erfolgen. Dies ist notwendig, um alle benutzten Test-Ressourcen wieder sauber freizugeben.

Listing 1 zeigt einen von der Klasse ActivityInstrumentationTestCase2 abgeleiteten JUnit-4-Test unter Berücksichtigung der eben beschriebenen Punkte.

Listing 1: JUnit 4 in Aktion
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MyJunit4ActivityInstrumentationTest
extends ActivityInstrumentationTestCase2 {

  private MyActivity mActivity;

  public MyJunit4ActivityInstrumentationTest() {
    super(MyActivity.class);
  }

  @Before
  public void setUp() throws Exception {
    super.setUp();
    injectInstrumentation(InstrumentationRegistry.getInstrumentation());
    mActivity = getActivity();
  }

  @Test
  public void checkPreconditions() {
    assertThat(mActivity, notNullValue());
    // Check that Instrumentation was correctly injected in setUp()
    assertThat(getInstrumentation(), notNullValue());
  }

  @After
  public void tearDown() throws Exception {
    super.tearDown();
  }

}

Fazit

Entgegen anders lautender Gerüchte und veralteter Ressourcen im Internet ist die Umsetzung von Unit Tests auch unter Verwendung des Android Studios problemlos möglich. Voraussetzung ist lediglich die Version 1.1+ der offiziellen Android-IDE sowie die Version 1.1.0+ des zugehörigen Gradle-Plug-ins.

Möchte man seine Tests mithilfe von JUnit 4 schreiben, um so zum Beispiel in den Genuss der Annotationen zu kommen, müssen zusätzlich einige Ressourcen des Android-Test-Kits eingebunden und ein spezieller Test Runner namens AndroidJUnitRunner verwendet werden. Der nächste logische Schritt wäre das Einbinden des Espresso-Test-Frameworks, welches mit der Version 2.1 noch einmal ein paar nützliche Features dazu bekommen hat. Das ist aber ein Thema für eine andere Kolumne. In diesem Sinne: Stay tuned …

Aufmacherbild: Smiling cute robotic toy via Shutterstock.com / Urheberrecht: Ociacia

Geschrieben von
Lars Röwekamp
Lars Röwekamp
Lars Röwekamp ist Gründer des IT-Beratungs- und Entwicklungsunternehmens open knowledge GmbH, beschäftigt sich im Rahmen seiner Tätigkeit als „CIO New Technologies“ mit der eingehenden Analyse und Bewertung neuer Software- und Technologietrends. Ein besonderer Schwerpunkt seiner Arbeit liegt derzeit in den Bereichen Enterprise und Mobile Computing, wobei neben Design- und Architekturfragen insbesondere die Real-Life-Aspekte im Fokus seiner Betrachtung stehen. Lars Röwekamp, Autor mehrerer Fachartikel und -bücher, beschäftigt sich seit der Geburtsstunde von Java mit dieser Programmiersprache, wobei er einen Großteil seiner praktischen Erfahrungen im Rahmen großer internationaler Projekte sammeln konnte.
Arne Limburg
Arne Limburg
Arne Limburg ist Softwarearchitekt bei der open knowledge GmbH in Oldenburg. Er verfügt über langjährige Erfahrung als Entwickler, Architekt und Consultant im Java-Umfeld und ist auch seit der ersten Stunde im Android-Umfeld aktiv.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: