Xamarin.Forms im Praxiseinsatz: Die Xamarin Test Cloud

15. Juli 2015

Eine der großen Herausforderungen in der Cross-Platform-Entwicklung ist es sicherzustellen, dass die zu entwickelnde App auf allen zu unterstützenden Geräten und OS-Versionen entsprechend funktioniert. Vor allem die Anzahl der unterschiedlichen Android Geräte und OS-Versionen ist beachtlich. Dieser Artikel beschreibt, wie die Xamarin Test Cloud durch automatisierte UI Acceptance Tests in der Cloud helfen kann, diese Fragmentierung zu meistern.

Features der Xamarin Test Cloud

Die Xamarin Test Cloud ermöglicht es eine App durch automatisierte UI Tests auf einer Vielzahl von physikalischen Geräten zu testen. Aktuell bietet die Xamarin Test Cloud 37 unterschiedliche Tablets und 137 Phones für die iOS und Android Plattform an. Windows Phone und Windows 8 werden nicht unterstützt. Die einzelnen Geräte stehen zusätzlich noch in unterschiedlichen OS-Versionen zur Verfügung. Eine detaillierte Übersicht findet man hier.

Für die Entwicklung der automatisierten UI Tests stellt Xamarin Unterstützung für zwei Frameworks zur Verfügung:

  • Xamarin.UITest: Dieses Framework ermöglicht die Entwicklung von in C# geschriebenen Tests unter der Verwendung von NUnit.
  • Calabash: Bei diesem Framework werden die Tests in Ruby geschrieben unter Verwendung von Cucumber. Cucumber ist ein Open Source Tool zur Unterstützung von Behavior Driven Development (BDD).

Im Folgenden konzentrieren wir uns auf das Xamarin.UITest Framework.

Notwendige Vorbereitungsschritte in der App

Damit die UI Tests mit der zu testenden App interagieren können, müssen die jeweiligen Controls über ein StyleId Property verfügen. Zusätzlich muss dieses Property noch in ein natives Property kopiert werden. Das genaue Vorgehen für iOS und Android ist im Detail hier beschrieben.

Entwicklung von Tests mit dem Xamarin.UITest Framework

Zunächst wird eine neue Class Library mit folgenden NuGet Packages angelegt:

Innerhalb der Class Library gibt es dann eine oder mehrere Klassen mit plattformunabhängigen Tests:

   1: public class CrossPlatformTests

   2:     {

   3:         protected IApp app;

   4:         

   5:         [SetUp]

   6:         public virtual void SetUp()

   7:         {

   8:             Assert.Ignore("This class requires a platform-specific bootstrapper" 

   9:             + " to override the `SetUp` method");

  10:         }

  11:  

  12:         [Test]

  13:         public void ClickingLoginButtonShouldShowErrorMessage()

  14:         {

  15:             Func<AppQuery, AppQuery> loginButton = c => c.Button("LoginButton");

  16:             Func<AppQuery, AppQuery> messageTextField = c => c.Id("message");

  17:  

  18:             this.app.Tap(loginButton);

  19:  

  20:             this.app.WaitForElement(messageTextField);

  21:             AppResult[] results = this.app.Query(messageTextField);

  22:  

  23:             this.app.Screenshot("Popup mit Fehlermeldung");

  24:  

  25:             Assert.AreEqual("Url, Benutzername und Passwort dürfen" 

  26:             + " nicht leer sein", results[0].Text);

  27:         }

  28:     }

Zusätzlich gibt es noch jeweils pro Plattform abgeleitet eine Klasse mit einem plattformspezifischen Setup und optional plattformspezifischen Tests:

   1: [TestFixture()]

   2:     public class AndroidTest : CrossPlatformTests

   3:     {

   4:         public string PathToAPK { get; set; }

   5:  

   6:  

   7:         [TestFixtureSetUp]

   8:         public void TestFixtureSetup()

   9:         {

  10:             string currentFile = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;

  11:             var fi = new FileInfo(currentFile);

  12:             string dir = fi.Directory.Parent.Parent.Parent.FullName;

  13:             this.PathToAPK = Path.Combine(dir, "KMS.Forms.Android", 

  14:             "bin", "Release", "eisTIK.mobile.apk");

  15:         }

  16:  

  17:         [SetUp]

  18:         public override void SetUp()

  19:         {

  20:             this.app = ConfigureApp.Android.ApkFile(this.PathToAPK)

  21:             .ApiKey("ENTER-YOUR-API-KEY-HERE").StartApp();

  22:         }

  23:     }

Ein detailliertes Tutorial zum Erstellen der Tests findet man hier.

Lokales Testen

Diese Tests können lokal auch ohne einen Test Cloud Account ausgeführt werden. Dabei gelten folgende Einschränkungen:

  • iOS Tests können nur gegen einen IOS Simulator ausgeführt werden.
  • Android Tests können nur gegen den Android Emulator oder den Xamarin Android Player ausgeführt werden.
  • Die Laufzeit eines Testszenarios ist auf 15 Minuten begrenzt.

Weitere Information diesbezüglich findet man hier.



Cloud Testing

Nachdem die UI Tests lokal erfolgreich durchgelaufen sind, können anschließend die Tests und die zu testende App direkt aus Visual Studio (Rechtsklick auf das Projekt mit den UI Tests und Klick auf "Run in Test Cloud…) in die Xamarin Test Cloud geladen werden. Hier werden noch die zu verwendenden Geräte ausgewählt und der Testlauf wird in der Xamarin Test Cloud vorgemerkt.xamarin test cloud - device selection

Sobald die jeweiligen Geräte in der Xamarin Test Cloud verfügbar sind, starten die Tests und abschließend ist ein konsolidierter Report verfügbar:

xamarin test cloud - report

Für jeden fehlgeschlagenen Test wird auch automatisch ein Screenshot von dem jeweiligen Gerät angelegt:

xamarin test cloud - screenshots



Kosten

Xamarin lässt sich die Test Cloud teuer bezahlen. Die kleinste Lizenz (Basic) kostet 1.000 Dollar im Monat und beinhaltet monatlich 200 Teststunden. Diese Grenze erreicht man leicht: Bei einem täglich zu durchlaufenden Testszenario von 1h auf 10 ausgewählten Kombinationen von Geräten und OS-Versionen kommt man schon auf 300 Teststunden im Monat (1h x 30 Tage x 10 Kombinationen von Gerät und OS-Version).

Fazit

Die Xamarin Test Cloud stellt eine teure, aber überzeugende Möglichkeit dar, sicherzustellen, dass sich die entwickelte iOS und Android App auf möglichst vielen Geräten wie geplant verhält. Was leider noch fehlt ist die Unterstützung für Windows und Windows Phone Geräte.