Xamarin.UITest: How to Retrieve All Elements in Li

2019-05-24 04:08发布

问题:

I have a list of 500 elements and when I use app.Query on the page, Xamarin.UITest gives me only 6 elements as only 6 elements are visible in UI.

How can I retrieve all 500 elements from the list inside of my UITest?

回答1:

As described above, the expected behavior of app.Query will only return the results of all visible controls on the page. Thus, if a control is not visible, app.Query will not return it.

The way to retrieve all of the data in a list is to use a Backdoor Method.

Xamarin has additional documentation on how to use backdoors in UITest.

Sample App

This sample app implements the snippets from the tutorial: https://github.com/brminnick/UITestSampleApp

Tutorial

1. Create a Serializable Object

Because Backdoor Methods are limited to return a string, we will need to be able to serialize our object.

You will need to add the Newtonsoft.Json NuGet package to each of your projects; i.e. add the Newtonsoft.Json NuGet to the .NET Standard project, the iOS Project, the Android Project and the UITest Project.

2. Create Static Methods to Serialize the Object

These methods will be used to serialize and deserialize the object.

using Newtonsoft.Json;

public static class ConverterHelpers
{
    public static string SerializeObject(object value)
    {
        return JsonConvert.SerializeObject(value);
    }

    public static T DeserializeObject<T>(string value)
    {
        return JsonConvert.DeserializeObject<T>(value);
    }
}

3. Add Backdoor Method to AppDelegate

This method in the AppDelegate will expose a backdoor from your iOS app that the UITest can utilize.

If you do not have an iOS app, skip this step.

[Export("getDataAsString:")]
public NSString GetDataAsString(NSString noValue)
{
    var data = [Add code here to retrieve the data from your app]

    var dataAsString = ConverterHelpers.SerializeObject(data);

    return new NSString(dataAsString);
}

4. Add Backdoor Method to MainActivity or Application class

This method in the MainActivity (or the Application class, if you have one) will expose a backdoor from your Android app that the UITest can utilize.

If you do not have an Android app, skip this step.

[Export("GetDataAsString")]
public string GetDataAsString()
{
    var data = [Add code here to retrieve the data from your app]

    var dataAsBase64String = ConverterHelpers.SerializeObject(data);

    return dataAsBase64String;
}

5. Create Static Method to Invoke Backdoors from UITest

Create a static method in the UITest project to invoke backdoor methods from UITest.

internal static List<DataModel> GetListData(IApp app)
{
    string dataAsString;

    if (app is iOSApp)
        dataAsString = app.Invoke("getDataAsString:", "").ToString();
    else
        dataAsString = app.Invoke("GetDataAsString").ToString();

    return ConverterHelpers.DeserializeObject<List<DataModel>>(dataAsString);
}

6. Invoke the Backdoor From The UITest

In the UITest test method, implement the static method to retrieve the data.

[Test]
public void VerifyData()
{
    Assert.IsTrue(GetListData(app).Count == 500);
}