Xamarin.UITest

Duration

20 minutes

Goals

The primary goal of this exercise will be to demonstrate another technique to create cross-platform UI Tests. In this approach, we will define an interface for each screen we want to test and then provide implementations for platform. The interfaces will abstract not just the queries, but the actual test mechanics. This can be very useful when the navigation and lower-level steps are different on a platform-by-platform basis.

You can continue from the prior lab exercise, or use the completed project available in Exercise 3.

Required Assets

The Exercise 4 folder has a completed version of the project to compare your results against.

Steps

Add the shared interface and implementations

To create cross-platform UI Tests, we need to provide an abstraction for interacting with the application - so we are not relying on the control types or even the text which might change from platform-to-platform.

  1. Add the following interface to your project:
public interface ITaskSystem
{
    ITaskSystem Add();
    ITaskSystem Delete(string name);

    ITaskSystem SetName(string name);
    ITaskSystem SetNotes (string notes);
    ITaskSystem Save();
    ITaskSystem Cancel();

    bool HasItem(string itemName);
}
  1. Examine the interface. This is the abstract definition against working on the application. This will control either the iOS or Android application. It includes all the methods necessary to add an item, delete an item and check to see if an item exists.
  2. Notice it is defined as a fluent interface where each method returns itself so you can string methods together to accomplish an overall goal.
  3. Select a platform you want to work with and let's implement each of the methods. Here's the purpose for each one:
  4. Method Description
    Add Adds a new Task by clicking the "Add" button. Must be on the main screen (list of tasks).
    Delete Deletes an existing Task by name by selecting the task and then clicking the "Delete" button on the details page. Must be on the main screen (list of tasks).
    SetName Sets the name/title for a task. Must be on the details screen.
    SetNotes Sets the notes/description for a task. Must be on the details screen.
    Save Saves changes to a task by clicking the "Save" button. Must be on the details screen.
    Cancel Cancels changes to a task by clicking the "Back" button. Must be on the details screen.
    HasItem Returns true or false whether a task with the given name exists in the task list. Must be on the main screen (list of tasks). Remember that `WaitForElement` throws a `SystemException` with an inner `TimeoutException` if it fails to find the element within the specified (or default) time. You will need to catch this exception to keep from failing the test.
  5. Add a new implementation file for your platform of choice and implement each of the methods. Use the existing tests you already created to add and delete a task to fill in the details for a given implementation. Here's some hints:
    • The constructor for your implementation should take an IApp and cache it off in an instance field.
    • Remember to return "this" from each method which returns an ITaskSystem.
    • For the Delete method, use a WaitForNoElement statement to wait for the specific task to be deleted.
    • Since we are implementing the full interaction, we can use the shortcut Marked queries where we just pass in the identifier text to look for.
    • For the Cancel method, use app.Back() on Android and app.Tap ("Cancel") on iOS.
    • For example, to add a new task from the main screen you would use the following code:

iOS

public ITaskSystem Add()
{
    app.Tap ("Add");
    return this;
}

Android

public ITaskSystem Add()
{
    app.Tap ("Add Task");
    return this;
}
  1. If you need some guidance, click the two hints below to show all the code for each platform. You can even consolidate common code in a base class if you like.

Show iOS Code

Show Android Code

Create the cross-platform UITests

Next, we will replace the code in our current tests with new interface-based, flient, cross-platform tests which run for both platforms.

  1. First, let's create our ITaskSystem implementation in the AppInitializer.cs code. Change the StartApp method to return a ITaskSystem implementation instead of the underlying IApp. Make sure to still create the IApp, just pass it into your implementation.

Show Code

  1. Next, open the Tests.cs file where your UITests are located. Update the code to cache off the new ITaskSystem interface instead of the IApp.
  2. Remove the AddANewTask method you used earlier, and all the query fields.
  3. Update your test methods to use your new abstraction - use the fluent syntax, for example:
ITaskSystem tasks;
...

// Add a new task
tasks
    .Add()
    .SetName("Get Milk")
    .SetNotes("Get some Milk")
    .Save();

Show Code

  1. Run the tests to make sure your UI tests still function - try it on both platforms if possible.

Summary

Congratulations, you have successfully created cross platform UI tests using an interface-based approach.

Go Back