Ejecutando una automatización de SerenityBDD para la misma aplicación disponible en diferentes sistemas operativos

Carlos Acevedo
BLOG DE TECNOLOGÍA DE DEVCO
3 min readMar 17, 2020

Imaginemos que tenemos una aplicación que decidimos realizar de forma nativa para iOS y Android y que los equipos de desarrollo serán 2 diferentes, sin embargo, el comportamiento de negocio y la aplicación deberán ser las mismas, ¿podríamos crear un único artefacto usando SerenityBDD para probar nuestra aplicación y que lo podamos ejecutar en los 2 sistemas sin repetir código?, en esta historia te mostraremos como lo logramos nosotros y podrás usar algunos artefactos nuestros para replicarlo en tu propia automatización.

El contexto

En Devco acompañamos a muchas empresas realizando automatizaciones Web, Desktop y Mobile usando SerenityBDD una de las mejores herramientas basadas en Selenium en el mercado para este tipo de automatizaciones. Dentro de las características que rescatamos de esta herramienta están: la documentación viva, es open source y tiene implementaciones propias de patrones de diseño para automatizaciones, lo que facilita a los equipos a construir automatizaciones que puedan ser sostenibles en el tiempo y que cuenten con las mejores prácticas del mercado.

En algunas de las empresas que apoyamos hemos encontrado varias veces el mismo problema: “Tenemos una aplicación móvil ya creada de forma nativa tanto para iOS como para Android y queremos realizar automatizaciones para facilitar la regresión cuando se realicen cambios sobre la aplicación, además los equipos de desarrollo son ser diferentes y sus prácticas también”. Con todo esto siempre vimos que la aplicación independiente de la tecnología que se use, suele seguir el mismo proceso de negocio y trata de ser consistente con la experiencia visual en las 2 tecnologías, por lo que los escenarios de pruebas son los mismos y únicamente cambian los Locators y algunas interacciones dependiendo de las tecnologías.

La solución

Decidimos crear una librería de automatización en Devco, donde será posible reutilizar interacciones y patrones que usamos para resolver problemas como el anteriormente descrito, esta librería es Open Source y esta publicada en GitHub.

Para usar la librería es suficiente con agregarla como dependencia en el proyecto, para Gradle sería modificar el build.gradle con la siguiente dependencia:

dependencies {implementation 'co.com.devco.automation:automationDevcoLibrary:1.3.1'}

Luego en la capa de User Interface de la arquitectura propuesta por Screenplay, se deben crear 2 nuevas capas: Pages y Locators. En los Pages se tendrán los Targets propuestos por SerenityBDD, pero en lugar de usar el Selenium Locator directamente, se deben usar unos métodos nuevos expuestos, tal como se muestra en el ejemplo:

import static co.com.devco.automation.mobile.locator.ElementFinder.theElementBy;public class YoutubeHomePage {    public static final Target BUTTON_FIND_VIDEO = Target.the("Button Video Finder").located(theElementBy(BUTTON_FIND_VIDEO_LOCATOR)); }

En los Locator se debe usar los Selenium Locators tanto para Android como para iOS, teniendo en cuenta que pueden ser diferentes como se muestra en el ejemplo:

import co.com.devco.automation.mobile.locator.Locator; 
import static co.com.devco.automation.mobile.locator.Locator.locator;
public class YoutubeHomeLocator {

public static final Locator BUTTON_FIND_VIDEO_LOCATOR = locator().withAndroidXpathStatic("//android.widget.ImageView[@content-desc='Buscar']").withIosXpathStatic("//XCUIElementTypeButton[@name='Buscar']");
}

Ahora revisemos un ejemplo usando un Locator dinámico, es decir un Locator que tiene una parte que cambia en tiempo de ejecución y que nos permite reutilizar el Locator.

import static co.com.devco.automation.mobile.locator.ElementFinder.dynamicElement;import static co.com.devco.userinterface.locators.ListedVideosLocator.CARD_VIDEO_LOCATOR; public class ListedVideosPage { 

public static final Target CARD_VIDEO = Target.the("Card listed videos").locatedBy(dynamicElement(CARD_VIDEO_LOCATOR));
}

Así con la selección dinámica podremos ubicar el ViewGroup y variar la descripción dependiendo del escenario a probar.

import co.com.devco.automation.mobile.locator.Locator; 
import static co.com.devco.automation.mobile.locator.Locator.locator;
public class ListedVideosLocator {

public static final Locator CARD_VIDEO_LOCATOR = locator().withAndroidXpathDynamic("//android.view.ViewGroup[contains(@content-desc,'{0}')]");
}

Con este código es suficiente para que dependiendo de los capabilities que esté usando la automatización en cada momento, sepa que Locator usar en cada ejecución, esta misma automatización correrá para iOS y para Android sin necesidad de cambiar el código.

Agradecimientos especiales a las personas que apoyaron en la construcción de esta solución en la librería Devco:

Juan de Jesús Fernández Graciano

@Daniel Torres Bedoya

@Susana Campo Contreras

--

--