¿Has desarrollado una aplicación móvil en Xamarin y quieres añadirle tests de UI (UITests)? Desde Solid Gear te enseñamos cómo hacerlo.
Xamarin.UITest es un framework de testing que permite que los tests escritos en NUnit sean ejecutados en aplicaciones iOS y Android. Se integra fácilmente en proyectos Xamarin.iOS y Xamarin.Android.
Añadir proyecto UITests a la solución
Lo primero que tenemos que hacer es crear un proyecto de tipo UI Test App en nuestra solución. En este será donde añadiremos los tests de interfaz de usuario para nuestra aplicación, y estos serán los que interactúen con la interfaz de usuario de la app tal y como un usuario lo haría: introduciendo texto, pulsando botones, manejando gestos, etc.
Por lo general, cada UITest se escribe como un método, que será un test. La clase que contiene el test se conoce como un test fixture. El text fixture contiene un test único o una agrupación lógica de tests y es responsable de ejecutar los tests y realizar la limpieza al terminar la ejecución.
using NUnit.Framework; using Xamarin.UITest; namespace UITests { [TestFixture(Platform.iOS)] public class LoginTests { IApp app; Platform platform; public LoginTests(Platform platform) { this.platform = platform; } [SetUp] public void BeforeEachTest() { app = AppInitializer.StartApp(platform); } [Test] public void Login() { //Login user app.Tap(x => x.Marked("usernameEntry")); app.EnterText(x => x.Marked("usernameEntry"), "test_user"); app.EnterText(x => x.Marked("passwordEntry"), "aaaaa"); app.Tap(x => x.Marked("loginButton")); app.Screenshot("Tapped Login"); } } }
Cómo añadir UITests para una pantalla de login
Lo primero que tenemos que hacer es, en el código de la vista de login, añadir la propiedad AutomationId (y darle un nombre) a los elementos sobre los que queramos tener control posteriormente en los tests. En nuestro caso, para el ejemplo que vamos a utilizar, se lo añadiremos a los campos de texto de usuario y password y al botón.
<?xml version="1.0" encoding="utf-8" ?> <local:LoginPageXaml xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:i18n="clr-namespace:LoginProject;assembly=LoginProject" xmlns:local="clr-namespace:LoginProject;assembly=LoginProject" x:Class="LoginProject.LoginPage" Title="{i18n:Translate app_name}" Style="{DynamicResource pageStyle}"> <local:LoginPageXaml.Resources> <ResourceDictionary> <local:InverseBooleanConverter x:Key="inverter"/> </ResourceDictionary> </local:LoginPageXaml.Resources> <local:LoginPageXaml.Content> <ScrollView> <StackLayout Orientation="Vertical"> <StackLayout Orientation="Vertical" Padding="0,25,0,0" HeightRequest="40" BackgroundColor="{DynamicResource redColor}"> <Label XAlign="Center" Text="{i18n:Translate app_name}" HorizontalOptions = "Center" VerticalOptions ="Center" FontSize="22" FontFamily="Roboto-Regular" TextColor="{DynamicResource whiteColor}"/> </StackLayout> <StackLayout Padding="25,30,25,0" Spacing="20" Orientation="Vertical"> <Label XAlign="Center" Text="{i18n:Translate auth_login_text}" FontFamily="Roboto-Light" FontSize="23" TextColor="{DynamicResource darkGray}"/> <Entry x:Name="UsernameEntry" AutomationId="usernameEntry" Text="{Binding Username}" Placeholder="{i18n:Translate auth_username}" FontFamily="Roboto-Regular" HeightRequest="45" FontSize="18" TextColor="{DynamicResource darkGray}" HorizontalOptions="FillAndExpand" VerticalOptions="Center" /> <Entry x:Name="PasswordEntry" AutomationId="passwordEntry" Text="{Binding Password}" Placeholder="{i18n:Translate auth_password}" FontFamily="Roboto-Regular" IsPassword="True" HeightRequest="45" FontSize="18" TextColor="{DynamicResource darkGray}" HorizontalOptions="FillAndExpand" VerticalOptions="Center" /> <Button x:Name="LoginButton" AutomationId="loginButton" Text="{i18n:Translate global_login}" Command="{Binding LoginCommand}" Style="{DynamicResource buttonStyle}" HeightRequest="45" FontFamily="Roboto-Medium" FontSize="20" /> </StackLayout> </StackLayout> </ScrollView> </local:LoginPageXaml.Content> </local:LoginPageXaml>
Posteriormente, si nos vamos a la clase Tests.cs del proyecto UITests, añadiremos el método para el testing de la funcionalidad de login.
Como nuestro test requiere de que escribamos el usuario y la contraseña en los campos correspondientes, utilizaremos el método IApp.EnterText de la siguiente forma
[Test] public void Login() { //Login user app.Tap(x => x.Marked("usernameEntry")); app.EnterText(x => x.Marked("usernameEntry"), "test_user"); app.EnterText(x => x.Marked("passwordEntry"), "aaaaa"); app.Tap(x => x.Marked("loginButton")); app.Screenshot("Tapped Login"); }
donde usernameEntry y passwordEntry son los AutomationId de los campos de tipo Entry en los que hay que introducir el texto. Posteriormente, una vez se han introducido los valores en dichos campos, utilizaremos el método IApp.Tap para simular el toque en el botón de «Login» que desencadena la validación de las credenciales contra el servidor.
Ejecución de los tests
Para ejecutar los Tests tenemos que seleccionar el proyecto UITests y el modo de despliegue.
En nuestro caso hemos seleccionado el modo Debug en un simulador de iPhone. Al darle al Play se nos abrirá un simulador e iremos viendo como la ejecución va introduciendo el usuario y la contraseña que hemos definido en los tests y posteriormente cómo se pulsa el botón de login.