Runar Ovesen Hjerpbakk

Software Philosopher

Xamarin.UITest for iOS is fickle when it comes to versioning

I’ve used Xamarin.UITest for both verifying the UI of my apps and automate screenshot taking for the App Store. This has worked, but with every iOS release, I’ve to tweak my tests to get them to run again.

This is what I had to do to get the default UITest template to run with Golden Ratio Calculator for iOS 12.

Making the tests run

1. Add the UI Test project to your solution

First, add the UI Test project to your solution.

2. Use updated packages, but not too updated

Xamarin.UITest does not support NUnit 3.x:

Xamarin.UITest requires NUnit 2.6.3 or 2.6.4 to run tests. Xamarin.UITest is not compatible with NUnit 3.x.

But the packages should still be updated to the latest supported versions. For Xamarin.UITest this is latest, for NUnit this is 2.7.0 at the time of writing.

3. Add Xamarin.TestCloud.Agent to your iOS project

The app itself needs Calabash in order to be automated by Xamarin.UITest. Add the latest version of Xamarin.TestCloud.Agent NuGet package to the iOS project.

4. Initialize Calabash in the iOS project

Then Calabash needs to be started when the app runs in the given configuration. Microsoft uses compiler directives so that Calabash only runs when needed.

At the beginning of the public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions) method of the AppDelegate class, add:

#if ENABLE_TEST_CLOUD
   Xamarin.Calabash.Start();
#endif

In my apps, I use DEBUG instead of ENABLE_TEST_CLOUD for convenience.

5. Reference the iOS project from the tests

Finally, the tests need to know about the app. Open the Unit Tests pad and add the iOS project as an app reference.

That’s it! Just run the tests and they will run using the selected simulator.

Enabling screenshots

If you want to use such tests to take screenshots, local screenshots need to be enabled like this:

iOSApp app;

[SetUp]
public void BeforeEachTest() {
   app = ConfigureApp
      .iOS
      .EnableLocalScreenshots()
      .StartApp();
}

Without EnableLocalScreenshots, taking screenshots like this:

[Test]
public void AppLaunches() {
   var fileInfo = app.Screenshot("First screen.");
}

will yield null instead of the FileInfo for the screenshot.