Automatización de Pruebas en Java con Selenium, Cucumber, Serenity, Junit y Page Object Model (BDD)

Ricardo Diaz Herrera
5 min readJul 2, 2019

Hace unos días estaba pensando en realizar un post que hablara de una de las tantas cosas que hago en el día a día, la automatización de pruebas software, las cuales actualmente tienen un papel fundamental en el ciclo de vida del desarrollo de software, pero ¿por qué?; -a lo mejor han escuchado hablar de TDD o BDD, donde sus siglas significan ‘Test Driven Development’ y ‘Behavior Driven Development’ respectivamente, y cabe resaltar que no son estrategias de testing si no que son técnicas de desarrollo, la última mencionada tiene como propósito definir un lenguaje común entre el negocio y técnicos, esto se realiza con el fin de integrar requisitos del negocio en el proceso de desarrollo, gracias a esto podemos mencionar a Gherkin (lenguaje comprensible para humanos y maquina), pero para esto se necesita una herramienta y es ahí cuando tenemos a cucumber, el cual permite la conexión entre gherkin y la interfaz de usuario que se desea realizar la prueba automatizada, tomando lo escrito en gherkin como los pasos para realizar dicha prueba (los cuales se escriben antes de escribir el código); sin embargo no basta con solo escribir lo que se desea probar, el solo no automatiza.

Para no dar más larga, a continuación veremos un proyecto de automatización de pruebas utilizando Java, Junit, Selenium , Cucumber , Page Object Model y Serenity para generar reporte, en este caso se automatiza una página de compras donde tomamos un producto al azar y comprobamos que el carrito esté lleno. Empecemos…

Como comentamos antes, primero debemos crear los pasos para la automatización, usando Gherkin.

Para ello creamos dentro de un source folder (src/test/resource) un package llamado features, y dentro de este, un file con esta convención [nombre].feature, es importante que incluyamos el .feature para que este sea reconocido y tendríamos algo como esto:

Fig1. estructura de creacion de un feature

NOTA: el nombre del feature debe especificar que es lo qué hace o contiene este feature

Dentro del feature escribimos los pasos que queremos que contenga nuestra automatización

Feature: Automated the your logo pageScenario: choose a product and it is displayed in the shopping cart successfullyGiven that I opened the browser at automationpractice pageWhen I look for 'dress' and select any displayed result to go to the shopping cartThen should the shopping cart show the product is not 'null'

Ahora bien debemos tener una conexión entre cucumber y el código, esto lo hacemos con ayuda de un Runner y stepdefinitions, donde el primero es el orquestador, gracias a él nuestro proyecto podrá ser ejecutado y permitirá esa conexión, y el stepdefinitions como su nombre lo dice tiene la definición de los pasos escritos en el feature, estos tendrán la implementación en código de los métodos que realizaran la automatización.

El runner quedaría de la siguiente forma :

StepDefinitions:

Para este proyecto hice uso de una clase Hook la cual se usa para realizar una instancia del driver (@Before) y quitarlo cuando finalice la prueba(@After). En este caso para el driver se hizo uso de una librería llamada webdrivermanager de bonigarcia.

Hook

Page Object Model

Siguiendo los que nos dice POM, debemos tener una clase por cada página que se va automatizar con el objetivo de obtener instancias de estas.

HomePage

SearchResultsPage

En esta clase es donde despues de buscar el producto , tomamos uno de la lista al azar.

ProductOverviewPage

Por ultimo se crea una page para la validación de la prueba

ShoppingCartSummaryPage

Todas estas pages heredan de un clase llamada BasePage, donde estan los métodos de click , escribir , espera hasta que sea visible y si existe un elemento.

BasePage

Utils

En este paquete llamado utils se encuentran dos clases, el PageGenerator que se usa para instanciar la clase dada y no tener que crear objetos de las clases pages ( implementado en los stepdefinitions), solo imagina un proyecto donde tengan muchas páginas, ¡sería algo muy extenso tener todos estos objetos!.

La otra clase StaticWait, lo único que hace es tener una espera estática, donde recibe como parámetros los segundos, el método que está en la clase los convierte de milisegundos a segundos.

PageGenerator

StaticWait

Archivo properties

Este archivo de propiedades es para la librería webdrivermanger y realice la configuración del driver.

webdrivermanager.properties

webdriver.chrome.driver.cache=${user.home}/.webdrivermanager/.cache/chromedriver
webdriver.gecko.driver.cache=${user.home}/.webdrivermanager/.cache/geckodriver
webdriver.opera.driver.cache=${user.home}/.webdrivermanager/.cache/operadriver
webdriver.edge.driver.cache=${user.home}/.webdrivermanager/.cache/msedgedriver

webdriver.chrome.driver.version=latest
webdriver.gecko.driver.version=latest
webdriver.opera.driver.version=latest
webdriver.edge.driver.version=latest

pom.xml

<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><serenity.report.resources.version>1.5.3</serenity.report.resources.version></properties><dependencies> <dependency>  <groupId>junit</groupId>  <artifactId>junit</artifactId>  <version>4.12</version>  <scope>test</scope></dependency><dependency>  <groupId>io.github.bonigarcia</groupId>  <artifactId>webdrivermanager</artifactId>  <version>3.6.1</version>  <scope>test</scope></dependency><dependency>  <groupId>org.apache.commons</groupId>  <artifactId>commons-lang3</artifactId>  <version>3.9</version>  </dependency><dependency>  <groupId>org.seleniumhq.selenium</groupId>  <artifactId>selenium-java</artifactId>  <version>3.141.59</version></dependency><dependency>  <groupId>net.serenity-bdd</groupId>  <artifactId>serenity-cucumber</artifactId>  <version>1.9.39</version></dependency><dependency>  <groupId>org.slf4j</groupId>  <artifactId>slf4j-simple</artifactId>  <version>1.6.1</version></dependency><dependency>  <groupId>net.serenity-bdd</groupId>  <artifactId>serenity-core</artifactId>  <version>2.0.54</version></dependency><dependency>  <groupId>net.serenity-bdd</groupId>  <artifactId>serenity-junit</artifactId>  <version>2.0.54</version></dependency><dependency>  <groupId>net.serenity-bdd</groupId>  <artifactId>serenity-reports</artifactId>  <version>2.0.54</version></dependency><dependency>  <groupId>org.apache.maven</groupId>  <artifactId>maven-plugin-api</artifactId>  <version>3.6.1</version></dependency><dependency>  <groupId>org.seleniumhq.selenium</groupId>  <artifactId>selenium-chrome-driver</artifactId>  <version>3.141.59</version></dependency></dependencies><build>  <plugins>     <plugin>      <groupId>org.apache.maven.plugins</groupId>      <artifactId>maven-compiler-plugin</artifactId>      <version>3.8.0</version> <configuration>  <source>1.8</source>  <target>1.8</target> <encoding>UTF-8</encoding></configuration></plugin><plugin> <groupId>net.serenity-bdd.maven.plugins</groupId> <artifactId>serenity-maven-plugin</artifactId> <version>2.0.54</version><dependencies><dependency>  <groupId>net.serenity-bdd</groupId>  <artifactId>serenity-core</artifactId>  <version>2.0.54</version></dependency></dependencies><executions>  <execution>    <id>serenity-reports</id>    <phase>post-integration-test</phase><goals>  <goal>aggregate</goal></goals></execution></executions>       </plugin>   </plugins></build>

Serenity

Serenity.properties

serenity.project.name = TestAutomation# Root package for any JUnit acceptance testsserenity.test.root= com.automationpractice.testing.testautomation.stepdefinitionsserenity.take.screenshots=BEFORE_AND_AFTER_EACH_STEPserenity.report.encoding=UTF-8

Reportes de Serenity

Conclusiones

PageObject Model con Page Factory para las pruebas automatizadas es muy beneficioso, dado que abarca buenas prácticas para las mismas y de igual manera es de mucha ayuda para el desarrollo ágil de software, donde se reduce considerablemente los errores en ambientes de calidad y producción, por ende el costo de mantenibilidad es mucho menor, otra ventaja a mencionar es que las pruebas automatizadas son un “analgésico” para las pruebas de regresión e integración, por el mismo hecho de ser automático facilita realizar pruebas que sean repetitivas y por ultimo nos presenta otra ventaja al utilizar Page Object Model, todos los localizadores de elementos se gestionan en un directorio separado y se pueden actualizar fácilmente sin ningún cambio en los casos de prueba.

En esta ocasión creé un proyecto sencillo para identificar las bondades que tiene BDD , POM ,Cucumber , Selenium y Serenity, al momento de realizar las pruebas automatizadas, que sea de utilidad para ustedes , como lo es para mí y que sea comprendido. Exitos!

--

--