Greg Shackles: Testing Xamarin Apps: Screen Object Pattern

Writing UI tests for Xamarin is awesome and easy using Xamarin.UITest, which allows you to write tests in C# that work across both iOS and Android. It provides a nice API to interact with your apps from test code, allowing for performing many common tasks for interacting with an app such as tapping elements, entering text, scrolling, swiping, etc.

Typical UI Tests

Using a tip calculator app as an example, here’s what one such test might look like:

[Test]
public void BrittleAndSadTest()  
{
    app.EnterText("SubTotal", "100.00");
    app.EnterText("TipPercentage", "20");

    var tipText = app.Query("TipAmount").First().Text;
    var totalText = app.Query("Total").First().Text;

    Assert.AreEqual("Tip: $20.00", tipText);
    Assert.AreEqual("Total: $120.00", totalText);
}

The test enters values in the text fields for sub total and tip percentage, queries the resulting tip amount and total out of the UI, and then asserts the values are correct. Pretty awesome, right? With just a few lines of code we’re verifying the expected behavior from the app from the same perspective as a user, ensuring the app is producing the expected results.

The Problem

One problem with this test is that in addition to validating the behavior of the app, it also has knowledge of how to query the values out of the UI. This is a very common pitfall in UI tests on any platform, and can lead to very brittle tests that start failing quickly as the UI evolves and the tests fall out of date.

All too often I’ve seen this result in failing tests being ignored as they become incompatible with updated interfaces, and ultimately they get abandoned completely. Thankfully, there’s a good solution to this that you should keep in mind right from the start when writing UI tests.

Screen Object Pattern

If you’re familiar with writing automated tests for the web using libraries such as Selenium you might already be familiar with the Page Object pattern. This is a pattern that works on any UI platform, and is not limited to just web applications. When working with mobile applications I personally like to refer to this as the Screen Object pattern, but it’s still effectively the same thing so feel free to use whichever term you prefer.

The basic idea is that instead of each test having deep knowledge of the UI and how to query it, you define classes that represent each screen and expose the appropriate methods and properties to interact with it. In this model, the screen class is the single place that needs to know how to find elements in the UI so if things change around and the queries need to be updated, you only need to update them in one place. On the other end, consumers of the class (e.g. the tests) get a nice typesafe API for interacting with these screens. This results in more readable and maintainable tests in the end.

Refactored Tests

Let’s take a look at what a screen object might look like for this screen:

class TipScreen  
{
    private readonly IApp _app;

    public TipScreen(IApp app)
    {
        _app = app;
    }

    public void EnterSubTotal(decimal subTotal)
    {
        _app.EnterText("SubTotal", subTotal.ToString());
    }

    public void EnterTipPercentage(int percentage)
    {
        _app.EnterText("TipPercentage", percentage.ToString());
    }

    public string TipText => _app.Query("TipAmount").First().Text;
    public string TotalText => _app.Query("Total").First().Text;
}

There’s not much magic here, which is really the point. The queries for interacting with the UI are all contained here, and exposed are simple methods for interacting with the screen. You can also see that the .ToString() calls on sub total and tip percentage are encapsulated inside of this class as well, so the exposed methods provide a nice typesafe API.

With this screen object in place we can update the test to make use of it:

[Test]
public void DurableAndAwesomeTest()  
{
    var screen = new TipScreen(app);
    screen.EnterSubTotal(100);
    screen.EnterTipPercentage(20);

    Assert.AreEqual("Tip: $20.00", screen.TipText);
    Assert.AreEqual("Total: $120.00", screen.TotalText);
}

Not only is the test more durable and resistant to change, it’s also far more readable now. Instead of being polluted with all the noise of UI queries, it now clearly shows the scenario being tested and the expected results of it.

If you’re writing any sort of UI tests, even very simple ones, I highly encourage you to start following this pattern. It makes it easier to write more tests and keep your apps stable and covered, and vastly improves the odds of you either losing a lot of time to keeping them up to date as your UI evolves, or even worse, ultimately abandoning them entirely.

Happy testing!

Michael Ridland: FreshMvvm n=2 – IOC and Constructor Injection

Here’s the next video in the  FreshMvvm n+1 series. The idea of this series is to get the video’s out to the eager listeners (you) as quickly as possible, therefore these videos are done live with almost no editing. Episode Title: n=2 – IOC and Constructor Injection In this episode we discuss: Review FreshMvvm’s built in IOC container […]

The post FreshMvvm n=2 – IOC and Constructor Injection appeared first on Michael Ridland.

Xamarin: Captio Apps Offer BYOD Expense Reporting

Captio was the first mobile app in Spain certified to capture electronic copies of receipts on behalf of companies and keep them for the mandatory five year period. Captio’s electronic receipts can be presented legally during an audit, meaning that customers can discard paper records they would otherwise have to physically store and manage. The […]

The post Captio Apps Offer BYOD Expense Reporting appeared first on Xamarin Blog.

Adam J Wolf: Weekly Xamarin Newsletter Issue #65

Watching some Xamarin.Forms TV I (adam) am back! Check out my new site XForms.TV and some brand new shows and episodes. Don’t delay: Try RC1 today! Miguel de Icaza, from Xamarin Inc., announced a new release candidate. Keep Users Engaged with iOS 9’s SFSafariViewController Mike James, from Xamarin Inc., shows you how to display web […]

The post Weekly Xamarin Newsletter Issue #65 appeared first on Syntax is my UI.

Adam J Wolf: Watching some Xamarin.Forms TV

Xamarin.Forms is missing something. At first, I couldn’t put my finger on it. Then it hit me. It needs it’s own TV station. A place to watch and learn about Xamarin.Forms, Xamarin Studio, and cross-platform development. Don’t get me wrong, we have other options but I think we can do better. I’m very happy to announce […]

The post Watching some Xamarin.Forms TV appeared first on Syntax is my UI.