[Xamarin] Xamarin UITest y Test Recorder desde Visual Studio

Bug - 02La calidad en movilidad cuesta

La calidad en el software es algo innegociable. Un buen proceso en el desarrollo y gestión del proceso es fundamental para conseguir ese objetivo. Debemos entregar Apps móviles perfectamente adaptadas a cada plataforma, ofreciendo la mejor experiencia de usuario posible pero sobretodo, funcional. Una App funcional debe cubrir y cumplir unos mínimos exigentes de calidad.

Como desarrolladores, somo humanos y el código no estara libre de errores. Sin embargo, el proceso que apliquemos para la detección y corrección a los mismos, es vital.

Podemos crear dos tipos de pruebas diferenciadas:

  • Pruebas unitarias: Pruebas de pequeñas unidades funcionales de nuestra App. Utilizaremos NUnit para realizar estas pruebas unitarias generalmente de ViewModels, Helpers y Servicios.
  • Pruebas de interfaz de usuario: Pruebas sobre la interfaz de usuario, escritura en cajas de texto, pulsaciones de botones, etc. Utilizaremos Xamarin UITest para estas pruebas.

Xamarin UITest

Xamarin.UITest es un framework de testing que permite realizar pruebas de comportamiento de la aplicación automatizando interacciones con la misma.

Integrado con Xamarin.iOS y Xamarin.Android, aunque puede usarse con proyectos iOS y Android escritos con Objective-C y Java, permite automatizar la gestión con la interfaz con pulsación de botones, introducir textos, gestos, tomar capturas, etc.

Cada UITest es un método escrito en C# que sigue el patrón Arrange-Act-Assert:

  • Arrange: El test inicializa todo lo necesario para que pueda ser lanzado.
  • Act: La interacción automatizada con la aplicación, introducir textos, pulsar botones, etc.
  • Assert: El test verifica resultados de las acciones realizadas en Act. Por ejemplo, verifica que tras introducir un valor incorrecto en una caja de texto, aparece un mensaje de error.

Nuestra aplicación:

Calculadora
Calculadora

Para poder analizar y profundizar en las pruebas, vamos a utilizar una aplicación realmente sencilla, una calculadora. Vamos a ver y analizar el proyecto de tipo Xamarin UITest de nuestra aplicación.

Todas las interacciones automatizadas con la aplicación ocurren mediante una instancia de Xamarin.UITest.IApp. Esta interfaz define los métodos utilizados para realizar la interacción. Cuenta con dos implementaciones:

  • Xamarin.UITest.iOS.iOSApp: Automatiza en aplicaciones iOS.
  • Xamarin.UITest.Android.AndroidApp: Automatiza en aplicaciones Android.

Ambos objetos, iOSApp y AndroidApp, se instancian utilizando la clase ConfigureApp. Esta clase se asegura de instanciar correctamente la aplicación en cada caso.

Tras instanciar la aplicación, la interacción con la aplicación se realiza utilizando querys. Los métodos de Xamarin.UITest esperan en la mayoría de casos un parámetro de tipo Func<AppQuery, AppQuery> para localizar los elementos visuales.

En nuestra aplicación, queremos realizar una prueba sencilla de suma, donde accederemos al botón numérico dos, al operador de suma y al símbolo igual. Esto nos permitirá verificar que el comportamiento de sumar dos más dos es el esperado.

Utilizando querys accedemos a cada elemento visual:

static readonly Func<AppQuery, AppQuery> TwoButton = c => c.Marked("Digit2");
static readonly Func<AppQuery, AppQuery> PlusButton = c => c.Marked("Operator+");
static readonly Func<AppQuery, AppQuery> EqualsButton = c => c.Marked("OperatorEquals");

Por supuesto, antes de lanzar el test, debemos realizar el proceso de inicialización de IApp. Normalmente, en una clase de tests tendremos agrupados múltiples tests. Cada uno de ellos debe correr en una condiciones limpias, es decir, se debe realizar la inicialización de IApp en cada caso. Este proceso se suele realizar en el método SetUp.

private IApp _app;

[SetUp]
public void SetUp()
{
     switch (TestEnvironment.Platform)
     {
          case TestPlatform.Local:
               var appFile =
                    new DirectoryInfo(Path.Combine("..", "..", "testapps"))
                        .GetFileSystemInfos()
                        .OrderByDescending(file => file.LastWriteTimeUtc)
                        .First(file => file.Name.EndsWith(".app") || file.Name.EndsWith(".apk"));

                _app = appFile.Name.EndsWith(".app")
                        ? ConfigureApp.iOS.AppBundle(appFile.FullName).StartApp() as IApp
                        : ConfigureApp.Android.ApkFile(appFile.FullName).StartApp();
                break;
           case TestPlatform.TestCloudiOS:
                _app = ConfigureApp.iOS.StartApp();
                break;
           case TestPlatform.TestCloudAndroid:
                _app = ConfigureApp.Android.StartApp();
                break;
     }
}

Por último, tras tener la inicialización (creada automáticamente al crear nuevo proyecto de tipo Xamarin UITest) y las querys, nuestro test de suma de dos más dos será:

[Test]
public void TheTwoPlusTwoIsFourTest()
{
     _app.WaitForElement(c => c.Marked("OperatorEquals"));

     _app.Tap(TwoButton);
     _app.Tap(PlusButton);
     _app.Tap(TwoButton);
     _app.Tap(EqualsButton);
     _app.Screenshot("When I get the result value");

     AppResult[] results = _app.WaitForElement(c => c.Marked("DisplayValue").Text("4"));

     Assert.IsTrue(results.Any());
}

Pulsamos en cada botón, tomamos captura del resultado y finalmente verificamos el resultado.

Corriendo Xamarin UITests desde Visual Studio

Para lanzar pruebas unitarias y Xamarin.UITests desde Visual Studio, utilizaremos el explorador de pruebas disponible desde el menu Test.

Explorador de pruebas
Explorador de pruebas

En nuestro proyecto con la calculadora realizada en Xamarin.Forms con pruebas con Xamarin.UITests vemos lo siguiente…

¿Por qué no aparecen los tests?
¿Por qué no aparecen los tests?

No aparecen, ¿qué ocurre?. El explorador de pruebas solo muestra por defecto tests realizados con MSTests. En nuestro proyecto Xamarin utilizamos NUnit para las pruebas unitarias y además XAmarin UITests, hace uso de NUnit también.

Vamos a solucionar el problema añadiendo la posibilidad de lanzar tests realizados con NUnit. Desde el menu de Herramientas->Extensiones y actualizaciones…

Extensions
Extensiones y actualizaciones

Dentro del conjunto Online buscamos por NUnit Test Adapter. Debemos instalar el adaptador correspondiente a NUnit 2 a pesar de estar disponible la versión correspondiente a NUnit 3. Esto es así ya que Xamarin UITest hace uso de la versión 2 de NUnit.

NUnit Test Adapter
NUnit Test Adapter

Tras instalar la extensión, al compilar el proyecto:

Aparecen los tests!
Aparecen los tests!

Ahora podemos lanzar o depurar cualquiera de las pruebas (o todas) sencillamente haciendo clic derecho sobre las mismas.

Xamarin Test Recorder

Podemos crear Xamarin UITests a mano y haciendo uso del REPL, sin embargo, es mucho más sencillo hacer uso de Xamarin Test Recorder.

Xamarin Test Recorder es una herramienta que nos permite, seleccionar un paquete de aplicación, lanzar la aplicación, interaccionar con la interfaz de usuario capturando los movimientos necesarios y la herramienta generará automáticamente el test en base a la interacción realizada.

Para poder utilizar la herramienta desde Visual Studio debemos instalar la extensión Xamarin Test Recorder 2015.

NOTA: Existe una versión de la extensión preparada para usar desde Visual Studio 2013.

Xamarin Test Recorder Extension
Xamarin Test Recorder Extension

Tras instalar la extensión, para poder utilizarla debemos cumplir unos requisitos básicos:

  1. Tener abierto un proyecto de tipo Xamarin UITest. En caso de no contar con ninguno en el proyecto, crear uno.
  2. Tener abierto un emulador o bien conectado por USB un dispositivo.

Tras cumplir los requisitos, podemos ver el siguiente indicador visual:

Indicador visual
Indicador visual

Pulsando sobre el indicador visual, nos aparecerá una opción para grabar un nuevo test.

Grabar nuevo test
Grabar nuevo test

En este punto, podremos elegir el paquete de la aplicación que deseamos probar.

Seleccionar paquete
Seleccionar paquete

Tras seleccionar el paquete de la aplicación, se lanzará la misma en el emulador o dispositivo conectado además de crear un nuevo método de Test vacío en el editor.

Con la aplicación en ejecución, y la grabación del test, cualquier interacción realizada quedará reflejada en un nuevo paso del nuevo método de test creado por la herramienta.

Una vez completada la interacción, vamos a detener la grabación. Pulsamos sobre el icono de grabación y nos aparecerá un menu como el siguiente:

Detener grabación
Detener grabación

Bastará con elegir la primera de las opciones para detener la grabación. Tendremos el código C# resultante de las interacciones realizadas en un nuevo método creado por la herramienta.

En el proceso de grabación del test, podemos tomar capturas de pantalla en cualquier momento pulsando sobre el icono de grabación y utilizando la opción Take Screenshot.

Sencillo, ¿cierto?. Las pruebas creadas las podemos lanzar directamente en local en nuestros emuladores o dispositivos físicos o hacer uso de Xamarin Test Cloud.

Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHub

Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *