We have been setting up a bunch of our projects lately to test with Xamarin’s awesome UI Testing framework, Xamarin.UITest. The general setup is pretty straightforward, but one of the biggest hurdles we have is consistently identifying controls for iOS. It doesn’t matter if we used Storyboards or did everything in code, getting consistent identifiers can be somewhat of a pain.

On Android, it is pretty much guaranteed that we will have IDs for important controls because when we setup the layout XML, we need them for all kinds of thing like layout and for retrieving our controls in the user interface later. Xamarin.UITest will pick up on this ID and we can use it later on for our user interface testing. So, there is not much else to do here.

For our iOS projects though, we generally are not assigning unique identifiers to the controls. As you can see in the example above, we never explicitly assign the ID. In Xamarin.iOS, we will almost always be dealing with an instance of a control, so we can just refer back to that object, no global identifier needed. This is true no matter how we setup our UI.

This becomes a problem when we want to start creating UI tests. How to we find our UI controls and how do we consistently refer back to them using Xamarin’s Xamarin.UITest?

One of the best ways of identifying controls for Xamarin.UITest is by using the AppQuery.Marked method. This will look at the AccessibilityLabel or AccessibilityId of a control on iOS.

If you didn’t do all of the work up front to map out all of your controls, though, going through your code and setting them later on can be quite a pain. After working with a couple of code bases created before Xamarin.UITest, I wanted an easy way to get all of those IDs.

So, I wrote a quick extension method for your ViewController to help you generate IDs for your application. Just add the following code to your app and call it after you have your controls setup in your ViewController. What this will do is scan through your properties and fields in your ViewController looking for Views. For any Views that it finds without an AccessibilityIdentifier, it will add one based on the variable’s name and report it out to the Debug window. So, it helps you two ways. You can use this while you are building out your test scripts and you can copy out the code from the debug window to add in the AccessibilityIdentifier to your control long term.

Now, the way that this is being used is not the most efficient™, so I added in some code in there to only allow this to run against a simulator. Additionaly, Xamarin.iOS for iOS 7 does not allow us to assign the AccessibilityIdentifier without some monkey business, so I prevent that too. If you want to have it run on a production environment, just remove the the simulator check.

What this is intended to do is give you a quick way to setup your UI Tests and generate the code you need to add to any missing controls in your ViewController while you are still developing. When you run your app, you should get some output in your Application or Debug Output window like this.

----- Missing View IDs for Login -----
----- Generated IDs for Fields -----
version.AccessibilityIdentifier = "version";
splashScreen.AccessibilityIdentifier = "splashScreen";
----- Generated IDs for Properties -----
View.AccessibilityIdentifier = "View";
----- Processing Time for Login : 29ms -----

Copy-and-Paste these generated IDs to update your controls and you should be good to go for testing long term. If you are using Xamarin.UITest and you are running a REPL, then you can continue developing your test and using the generated IDs for your ViewController.

Now, we have a nice and easy way to get IDs for our controls without having to do too much additional work.