About Xamarin.Forms Application Testing (Legacy)

Applies to TestComplete 15.63, last modified on April 23, 2024
The information below concerns legacy mobile tests that work with mobile devices connected to the local computer. For new mobile tests, we recommend using the newer cloud-compatible approach.

TestComplete supports testing of mobile Xamarin.Forms applications. This topic helps you learn how to test Xamarin.Forms applications with TestComplete.

Supported Xamarin Applications

With TestComplete, you can test Xamarin.Forms, Xamarin.Android and Xamarin.iOS applications:

  • Xamarin.Forms. TestComplete recognizes controls in Xamarin.Forms applications and offers special wrapper test objects with control-specific methods and properties for simulating user actions on these controls. This topic overviews the details of this support.

  • Xamarin.Android and Xamarin.iOS. TestComplete recognizes controls in these applications as “native” Android or iOS controls. You prepare these applications and run them in the same way you do this when working with regular Android and iOS apps. See Testing Android Applications (Legacy) and Testing iOS Applications (Legacy).

  • Rg.Plugins.Popup. TestComplete recognizes Xamarin.Forms controls inside containers created with the Rg.Plugins.Popup library.

Supported Xamarin.Forms Applications

TestComplete can test applications created with Xamarin.Forms version 2.5.0.

These applications can be compiled with any development tool, but they should run on the supported operating systems:

  • Android

    Running on Android 4.0.1 - 4.4.x, 5.0 - 5.1.1, 6.0, 7.0 - 7.1.1, 8.0 - 8.1, 9.0 (API Level 15 - 19, 21 - 28), 10.0, 11.0 on one of the supported devices.

  • iOS

    Running on iOS 13.0 - 13.7, 14.0 - 14.7, iPadOS 13.0 - 13.7, 14.0 - 14.8, 15.0 - 15.3 on one of the supported devices.

    Note: You may experience performance issues during test recording and playback on older iOS devices like iPhone 5S.

Requirements and Preparations

To create and run tests for your Xamarin.Forms applications, you need to prepare your application and your testing environment for testing. The way you can do this depends on the mobile platform you use:

Creating and Recording Tests

In TestComplete, you can record tests or create tests manually as keyword tests or scripts. It is usually easier to record a test first and then modify it.

When recording a test, you interact with your mobile application as an end-user would: navigate through application screens, fill out forms, and so on. TestComplete captures all the actions you perform in the application and adds them to the test.

A test consists of a sequence of operations with the device and objects of the tested application. For example, the following keyword test uses the SetText operation to simulate text input into text boxes, and the Touch operation to simulate touching a control:

A sample test for Xamarin.Forms Application

You can improve and modify the recorded tests in a number of ways to create more flexible and efficient tests. For example, you can:

  • Add new operations to the recorded tests, reorder operations and modify their parameters.

  • Delete or disable unneeded operations (for example, superfluous operations).

  • Insert checkpoints to verify the state of the tested application.

  • Create data-driven tests that run multiple test iterations using different sets of data.

The following topics provide detailed information about creating and enhancing tests:

Task See topic …
Simulating user actions Working With Application Objects and Controls
Recording tests Recording Automated Tests
Creating tests manually Keyword Tests and About Script Tests
Running Tests Running Tests
Verifying application behavior and state About Checkpoints
Running multiple test iterations using data sets Data-Driven Testing

What Your Tests Can Do

You can record or manually create tests that will perform various test actions against Xamarin.Forms applications:

  • Simulate touches and long touches

  • Simulate swipes

  • Input text

  • Verify the state of objects and their properties

  • Call methods and properties of controls

  • And so on.

To simulate user actions on your tested application, you can use the methods and properties TestComplete provides for Xamarin.Forms controls. For information on the available methods and properties, see Supported Xamarin.Forms Controls.

Mobile Screen Window

TestComplete includes the Mobile Screen window that shows the screen of the mobile device (or emulator or virtual machine) where your tested application is running:

The Mobile Screen of Xamarin.Forms applications

Click the image to enlarge it.

The Mobile Screen window makes the application screen as accessible as your computer’s desktop. When you perform various actions in this window, like touches, swipes or keystrokes, TestComplete passes them to the application under test. Similarly, any changes on the application screen are reflected in this window. In other words, you can use the Mobile Screen window to work with a Xamarin.Forms application without accessing your mobile device.

Object Hierarchy and Object Properties

You can explore the hierarchy of your tested Xamarin.Forms application in the Object Browser in TestComplete:

Xamarin.Forms objects in the Object Browser

Click the image to enlarge it.

The top-level object for Xamarin.Forms applications is Mobile. It provides access to the mobile devices to which TestComplete is connected. The child Device objects of the Mobile object correspond to the connected devices. Below Device, there is the Process object that corresponds to your tested application. Note: If there are no prepared applications running on a device, the Device node has no child nodes.

The object hierarchy of the process node corresponds to the inner hierarchy of controls in your application.

TestComplete recognizes objects in Xamarin.Forms applications as cross-platform Xamarin.Forms objects. These objects are the same both for the Android and iOS platforms:

The Xamarin.Forms application running on an iOS device

Click the image to enlarge it.

A Xamarin.Forms application running on an iOS device

The Xamarin.Forms application running on an Android device

Click the image to enlarge it.

A Xamarin.Forms application running on an Android device

TestComplete detects control class names and text, and uses them to name test objects: XFObject("Button","Click Me!"), Label("Native label") and so on. If an object has no text, its name looks like XFObject("Button", ""). If there are several objects that contain the same text (or do not contain any text), TestComplete adds indexes to their names to distinguish the objects: XFObject("Button", ""), XFObject("Button", "",2), and so on.

To simulate user actions on Xamarin.Forms objects, you use the methods and properties TestComplete provides. See Xamarin.Forms Objects.

If a Xamarin.Forms application includes platform-specific objects, TestComplete will recognize them as appropriate Android or iOS objects.

You can easily create and run cross-platform tests for your Xamarin.Forms applications both on Android and on iOS devices.

To create cross-platform tests: Your tested application must not have platform-specific objects and must have the same object hierarchy for the Android and iOS platforms.
You may also need to modify your recorded tests to be able to run them both on Android and on iOS devices. For instance, you will have to modify hard-coded coordinates that TestComplete records (for example, for the Touch method). Coordinate values recorded for one platform will not be applicable when running the test on another platform.
In addition, if you use Name Mapping, you will have to modify recognition parameters for your mobile devices to allow TestComplete to run your tests on both platforms. See Note on Mapping Device Objects.

Verifying Object Properties

To verify the properties of Xamarin.Forms application objects, you can use property checkpoints. You can also use region checkpoints to compare the device screen or its part with some baseline image.

You can find a detailed description of how to create checkpoints for Xamarin.Forms applications in the Checkpoints section.

When creating checkpoints, you specify the object you want to verify by selecting it in the Mobile Screen window in TestComplete (rather than on the actual screen of your mobile device, for example).

Sample

TestComplete includes a sample test project that illustrates testing of a Xamarin.Forms application:

<TestComplete Samples>\Mobile\Xamarin.Forms\Orders

Note: If you do not have the sample, download the TestComplete Samples installation package from the support.smartbear.com/testcomplete/downloads/samples page of our website and run it.

How Do I Start?

To learn how to create a simple test for a Xamarin.Forms application, follow this tutorial:

Testing Xamarin.Forms Applications - Tutorial (Legacy)

Known Issues

  • TestComplete may fail to record user actions in Xamarin.Forms applications. For example, sometimes, it may record redundant method calls, or it may record user input incorrectly.

    TestComplete may also fail to record Keys actions for text edit controls in Xamarin.Forms applications running on Android devices, for example, for multiline text edit controls or in-place text editors of list view controls. To avoid this issue, you can configure your Android device to use the TestComplete Android Agent keyboard instead of its native on-screen keyboard during test recording. To learn about the Agent keyboard, see About TestComplete Android Agent Keyboard (Legacy).

  • TestComplete can record and simulate user actions only against the Back button of the Page control. The other ToolbarItem objects are not supported. To simulate user actions on them, use “native”  properties and methods of the Page control. You can use the native ToolbarItems property to get a scripting interface to the control’s buttons, and then use methods and properties of a button object to work with that button.

    The following example demonstrates how you can get access to ToolbarItem elements:

    JavaScript, JScript

    function toolbarItemsTest()
    {
      // Get a page with ToolbarItems
      var page = Mobile.Device("iPhone").Process("Orders").XFObject("MainPage", "").XFObject("NavigationPage", "Orders").XFObject("OrdersPage", "Orders Sample");
      // Access a toolbar item
      var toolbarItem = page.ToolbarItems.Item(0);
      // Activate the item
      toolbarItem.Activate();
    }

    Python

    def toolbarItemsTest():
      # Get a page with ToolbarItems
      page = Mobile.Device("iPhone").Process("Orders").XFObject("MainPage", "").XFObject("NavigationPage", "Orders").XFObject("OrdersPage", "Orders Sample")
      # Access a toolbar item 
      toolbarItem = page.ToolbarItems.Item[0]
      # Activate the item
      toolbarItem.Activate()

    VBScript

    Sub toolbarItemsTest
      Dim page, toolbarItem
      ' Get a page with ToolbarItems
      Set page = Mobile.Device("iPhone").Process("Orders").XFObject("MainPage", "").XFObject("NavigationPage", "Orders").XFObject("OrdersPage", "Orders Sample")
      ' Access a toolbar item
      Set toolbarItem = page.ToolbarItems.Item(0)
      ' Activate the item
      toolbarItem.Activate()
    End Sub

    DelphiScript

    procedure toolbarItemsTest;
    var page, toolbarItem;
    begin
      // Get a page with ToolbarItems
      page := Mobile.Device('iPhone').Process('Orders').XFObject('MainPage', '').XFObject('NavigationPage', 'Orders').XFObject('OrdersPage', 'Orders Sample');
      // Access a toolbar item
                 toolbarItem := page.ToolbarItems.Item(0);
      // Activate the item
      toolbarItem.Activate();
    end;

    C++Script, C#Script

    function toolbarItemsTest()
    {
      // Getting a page with ToolbarItems
      var page = Mobile["Device"]("iPhone")["Process"]("Orders")["XFObject"]("MainPage", "")["XFObject"]("NavigationPage", "Orders")["XFObject"]("OrdersPage", "Orders Sample");
      // Access a toolbar item
      var toolbarItem = page["ToolbarItems"]()["Item"](0);
      // Activate the item
      toolbarItem["Activate"]();
    }

  • Currently, TestComplete does not recognize the type of the TableView and ListView cells (SwitchCell, EntryCell and others), and does not provide cell-specific methods and properties. For example, if a cell contains a check box or a text box, TestComplete will not provide checkbox- or textbox-specific methods for simulating user actions on that cell. To simulate user actions in this case, use “native” methods and properties of cell objects.

    The following example demonstrates how you can access the SwitchCell and TextCell cells of the TableView and ListView controls by using native properties:

    JavaScript, JScript

    function Test()
    {
      // Get the TableView control
      var tableView = Mobile.Device("iPhone").Process("TestedApp").XFObject("NavigationPage", "").XFObject("TableViews", "TableViews").XFObject("Grid", "").XFObject("TableView", "");
      // Enable the SwitchCell item of the TableView control
      tableView.Root.Item(1).Item(0).On = true;
      // Change the text of the TextCell item of the TableView control
      tableView.Root.Item(2).Item(0).Text = "NewCell";

      // Get the ListView control
      var listView = Mobile.Device("iPhone").Process("TestedApp").XFObject("NavigationPage", "").XFObject("ListViews", "ListViews").XFObject("Grid", "").XFObject("ListView", "");
      // Disable the SwitchCell item of the ListView control
      listView.TemplatedItems.Item(0).On = false;
      // Change the text of the TextCell item of the ListView control
      listView.TemplatedItems.Item(1).Text = "NewCell";
    }

    Python

    def Test():
      # Get the TableView control
      tableView = Mobile.Device("iPhone").Process("TestedApp").XFObject("NavigationPage", "").XFObject("TableViews", "TableViews").XFObject("Grid", "").XFObject("TableView", "")
      # Enable the SwitchCell item of the TableView control 
      tableView.Root.Item[1].Item[0].On = True
      # Change the text of the TextCell item of the TableView control
      tableView.Root.Item[2].Item[0].Text = "NewCell"
      
      # Get the ListView control
      listView = Mobile.Device("iPhone").Process("TestedApp").XFObject("NavigationPage", "").XFObject("ListViews", "ListViews").XFObject("Grid", "").XFObject("ListView", "")
      # Disable the SwitchCell item of the ListView control
      listView.TemplatedItems.Item[0].On = False
      # Change the text of the TextCell item of the ListView control
      listView.TemplatedItems.Item[1].Text = "NewCell"

    VBScript

    Sub Test
      Dim tableView, listView
      ' Get the TableView control
      Set tableView = Mobile.Device("iPhone").Process("TestedApp").XFObject("NavigationPage", "").XFObject("TableViews", "TableViews").XFObject("Grid", "").XFObject("TableView", "")
      ' Enable the SwitchCell item of the TableView control
      tableView.Root.Item(1).Item(0).On = True
      ' Change the text of the TextCell item of the TableView control
      tableView.Root.Item(2).Item(0).Text = "NewCell"

      ' Get the ListView control
      Set listView = Mobile.Device("iPhone").Process("TestedApp").XFObject("NavigationPage", "").XFObject("ListViews", "ListViews").XFObject("Grid", "").XFObject("ListView", "")
      ' Disable the SwitchCell item of the ListView control
      listView.TemplatedItems.Item(0).On = False
      ' Change the text of the TextCell item of the ListView control
      listView.TemplatedItems.Item(1).Text = "NewCell"
    End Sub

    DelphiScript

    procedure Test;
    var tableView, listView;
    begin
      // Get the TableView control
      tableView := Mobile.Device('iPhone').Process('TestedApp').XFObject('NavigationPage', '').XFObject('TableViews', 'TableViews').XFObject('Grid', '').XFObject('TableView', '');
      // Enable the SwitchCell item of the TableView control
      tableView.Root.Item(1).Item(0).On := true;
      // Change the text of the TextCell item of the TableView control
      tableView.Root.Item(2).Item(0).Text := 'NewCell';

      // Get the ListView control
      listView := Mobile.Device('iPhone').Process('TestedApp').XFObject('NavigationPage', '').XFObject('ListViews', 'ListViews').XFObject('Grid', '').XFObject('ListView', '');
      // Disable the SwitchCell item of the ListView control
      listView.TemplatedItems.Item(0).On := false;
      // Change the text of the TextCell item of the ListView control
      listView.TemplatedItems.Item(1).Text := 'NewCell';
    end;

    C++Script, C#Script

    function Test()
    {
      // Get the TableView control
       var tableView = Mobile["Device"]("iPhone")["Process"]("TestedApp")["XFObject"]("NavigationPage", "")[XFObject]("TableViews", "TableViews")[XFObject]("Grid", "")["XFObject"]("TableView", "");
      // Enable the SwitchCell item of the TableView control
      tableView["Root"]()["Item"](1)["Item"](0)["On"]() = true;
      // Change the text of the TextCell item of the TableView control
      tableView["Root"]()["Item"](2)["Item"](0)["Text"]() = "NewCell";

      // Get the ListView control
       var listView = Mobile["Device"]("iPhone")["Process"]("TestedApp")["XFObject"]("NavigationPage", "")XFObject("ListViews", "ListViews")[XFObject]("Grid", "")["XFObject"]("ListView", "");
      // Disable the SwitchCell item of the ListView control
      listView["TemplatedItems"]()["Item"](0)["On"]() = false;
      // CChange the text of the TextCell item of the ListView control
      listView["TemplatedItems"]()["Item"](1)["Text"]() = "NewCell";
    }

  • Now, you can access ListView items only by their indexes. To access the items by their captions, use their native properties.

    The following example demonstrates how you can get item indexes of ListView controls via native ItemsSource property if you know the field captions of the corresponding items:

    JavaScript, JScript

    function Test()
     {
       var customerName = "Samuel Clemens";
       // Get the ListView control
       var listView = Mobile.Device("HTC One S").Process("Orders.Orders").XFObject("MainPage", "").XFObject("NavigationPage", "Orders").XFObject("OrdersPage", "Orders Sample").XFObject("ScrollView", "").XFObject("Grid", "").XFObject("ItemsListView");
       //Post the index of the ListView item that has the Samuel Clemens value in the castomerName field
       Log.Message(FindItem(listView, customerName));
     }

    function FindItem(listView, customerName)
     {
       for (var i = 0; i < listView.ItemsSource.Count; ++i)
         if (listView.ItemsSource.Item(i).CustomerName == customerName)
           return i;
       return -1;
     }

    Python

    def Test():
      customerName = "Samuel Clemens"
      # Get the ListView control
      listView = Mobile.Device("HTC One S").Process("Orders.Orders").XFObject("MainPage", "").XFObject("NavigationPage", "Orders").XFObject("OrdersPage", "Orders Sample").XFObject("ScrollView", "").XFObject("Grid", "").XFObject("ItemsListView")
      # Post the index of the ListView item that has the Samuel Clemens value in the castomerName field
      Log.Message(FindItem(listView, customerName))
    
    
    def FindItem(listView, customerName):
      for i in range (listView.ItemsSource.Count):
        if listView.ItemsSource.Item[i].CustomerName == customerName:
          return i
      return -1

    VBScript

    Sub Test
      Dim listView, customerName
      customerName = "Samuel Clemens"
      ' Get the ListView control
      Set listView = Mobile.Device("HTC One S").Process("Orders.Orders").XFObject("MainPage", "").XFObject("NavigationPage", "Orders").XFObject("OrdersPage", "Orders Sample").XFObject("ScrollView", "").XFObject("Grid", "").XFObject("ItemsListView")
      ' Post the index of the ListView item that has the Samuel Clemens value in the castomerName field
      Log.Message(FindItem(listView, customerName))
    End Sub

    Function FindItem(listView, customerName)
      Dim i, index
      index = -1
      For i = 0 To listView.ItemsSource.Count-1
        IF listView.ItemsSource.Item(i).CustomerName = customerName Then
          index = i
          Exit For
        End If
      Next
      FindItem = index
    End Function

    DelphiScript

    function FindItem(listView, customerName);
    var i;
    begin
       for i := 0 to listView.ItemsSource.Count - 1 do
       begin
        if listView.ItemsSource.Item[i].CustomerName = customerName then
        begin
          Result := i;
          exit;
        end;
       end;
      Result := -1;
    end;

    procedure Test;
    var listView, customerName;
    begin
       customerName := 'Samuel Clemens';
       // Get the ListView control
       listView := Mobile.Device('HTC One S').Process('Orders.Orders').XFObject('MainPage', '').XFObject('NavigationPage', 'Orders').XFObject('OrdersPage', 'Orders Sample').XFObject('ScrollView', '').XFObject('Grid', '').XFObject('ItemsListView');
       // Post the index of the ListView item that has the Samuel Clemens value in the castomerName field
       Log.Message(FindItem(listView, customerName));
    end;

    C++Script, C#Script

    function Test()
     {
       var customerName = "Samuel Clemens";
       // Get the ListView control
       var listView = Mobile["Device"]("HTC One S")["Process"]("Orders.Orders")["XFObject"]("MainPage", "")["XFObject"]("NavigationPage", "Orders")["XFObject"]("OrdersPage", "Orders Sample")["XFObject"]("ScrollView", "")["XFObject"]("Grid", "")["XFObject"]("ItemsListView");
       //Post the index of the ListView item that has the Samuel Clemens value in the castomerName field
       Log["Message"](FindItem(listView, customerName));
     }

    function FindItem(listView, customerName)
     {
       for (var i = 0; i < listView["ItemsSource"]["Count"]; ++i)
         if (listView["ItemsSource"]["Item"](i)["CustomerName"] == customerName)
           return i;
       return -1;
     }

  • You may experience performance issues during test recording and playback on older iOS devices like iPhone 5S. As a workaround, we recommend that you use up-to-date iOS devices, if possible.

  • Xamarin.Forms applications are regular Android or iOS applications. When testing them, you may face the same issues you face when testing regular Android and iOS apps.

    For instance, when running tests on iOS devices, TestComplete does not detect animation playback, and does not wait for the animation to complete. If the target control over which TestComplete is going to simulate user actions is not available until the animation completes, your test will fail. You may face this issue when testing Xamarin.Forms applications as well, for example, when navigating between pages of the NavigationPage control. To learn about possible workarounds, see the animation playback issue description for iOS.

See Also

Testing Mobile Applications
Preparing Xamarin.Forms Applications for Testing (Legacy)
Supported Xamarin.Forms Controls

Highlight search results