Pruebas funcionales con Geb en una aplicación web Java

Escrito por el , actualizado el .
java planeta-codigo programacion
Enlace permanente Comentarios

Geb

Java

Las pruebas automatizados permiten comprobar que una aplicación se comporta de la manera esperada en los casos probados, creando pruebas automatizadas se evita hacer las aburridas y repetitivas pruebas manuales que consumen gran cantidad de tiempo. Hay diferentes categorías de pruebas: unitarias, de integración y las funcionales. Para las pruebas unitarias y de integración en la plataforma Java unas de las más populares herramientas son JUnit y Spock, para las pruebas funcionales están Selenium y la herramienta que explicaré en este artículo Geb que puede usarse junto con Spock haciendo que el código de los teses sea muy descriptivo.

Geb soporta una APi similar a la que emplea jQuery para la interacción con los elementos de la página bajo pruebas. Este ejemplo prueba a ir a la página del buscador Google y que el resultado es el esperado usando alguna de las múltiples formas de interacción con el contenido de la página.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package io.github.picodotdev.plugintapestry.geb

import geb.spock.GebSpec
 
class GoogleSpec extends GebSpec {
    def 'go to google'() {
        when:
        go 'http://www.google.es'
 
        then:
        title == 'Google'
    }
}
GoogleSpec.groovy

Para hacer más sencillos las pruebas se pueden describir las páginas, sus URLs y los elementos que contienen. Para ello hay que crear una clase que extienda de Page y definir propiedades como url, at y content, se pueden incluso definir métodos. En la documentación de Geb está más detallado la definición de las páginas. También se pueden crear módulos para definir elementos comunes a varias páginas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package io.github.picodotdev.plugintapestry.geb

import geb.Page
import geb.spock.GebSpec

import org.springframework.boot.test.context.SpringBootTest

import io.github.picodotdev.plugintapestry.spring.AppConfiguration

// Definición de la página índice 
class IndexPage extends Page {
    // Localización
    static url = 'https://localhost:8443/'
    // Determinar que se cargó una página 
    static at = { title.startsWith('PlugIn') }
    // Definición de los elementos de la página
    static content = {
        meta { $('meta[pagina]') }
    }
}

@SpringBootTest(classes = AppConfiguration.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class IndexSpec extends GebSpec {
    def 'go to index'() {
        when:
        to IndexPage

        then:
	meta.@pagina == 'Index'
   }
}
IndexSpec.groovy

La automatización de las pruebas además de comprobar que la página devuelva es la esperada, en el caso de estos ejemplo con una propiedad meta o con el título de la página, consiste en realizar las interacciones que un usuario realizaría como introducir datos en formularios, hacer clic en elementos de una página y comprobar la presencia de elementos que valide la prueba. Con esta herramienta se pueden probar los casos y flujos funcionales más importantes de la aplicación como sería el proceso de compra en una aplicación de comercio electrónico y la búsqueda, alta y modificación de un registro en la aplicación de gestión.

En este ejemplo se realiza una búsqueda en Google y se comprueba el resultado devuelto. Primero se accede a ella con la sentencia to, se introduce el texto de búsqueda Chuck Norris y se pulsa el botón de búsqueda. La comprobación consiste en asegurar que la página devuelta es la página de resultados de búsqueda con la sentencia at y que el primer resultado de la búsqueda contiene la palabra Chuck, GoogleHomePage define la página de búsqueda, GoogleResultsPage la página de resultados y GoogleSearchSpec contiene la interacción de la prueba.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package io.github.picodotdev.plugintapestry.geb

import geb.Page
import geb.spock.GebSpec
 
class GoogleHomePage extends Page {
    static url = 'https://www.google.es/'
    static at = { title == 'Google' }
    static content = {
        searchField { $("input[name=q]") }
        searchButton(to: GoogleResultsPage) { $("input[value='Buscar con Google']") }
    }
}

class GoogleResultsPage extends Page {
    static at = { waitFor { title.endsWith("Buscar con Google") } }
    static content = {
        results(wait: true) { $("div.g") }
        result { index -> return results[index] }
        resultLink { index -> result(index).find("h3.r a") }
    }
}

class GoogleSearchSpec extends GebSpec {
    def 'go to google'() {
        when:
        to GoogleHomePage
    	searchField().value "Chuck Norris"
	searchButton().click()

        then:
	at GoogleResultsPage
    	resultLink(0).text().contains("Chuck")
   }
}
GoogleSearchSpec.groovy

Las dependencias de Geb necesarias a incluir en el archivo de configuración de la herramienta de gestión del proyecto usando Gradle son las siguientes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
...

dependencies {
    ...
    testCompile "org.seleniumhq.selenium:selenium-java:$versions.selenium"
    testCompile "org.seleniumhq.selenium:selenium-server:$versions.selenium"
    ...
    testCompile "org.gebish:geb-spock:$versions.geb"
    testCompile "org.gebish:geb-junit4:$versions.geb"
    testCompile ("org.springframework.boot:spring-boot-starter-test:$versions.spring_boot") { exclude(group: 'org.springframework.boot', module: 'spring-boot-starter-logging') }
    ...
}

...
build-dependencies.gradle

Usando una aplicación con Spring Boot para ejecutar los teses de integración se debe iniciar la aplicación web previamente con la anotación SpringBootTest mostrado en el caso IndexSpec además de excluir los teses de integración y los unitarios de los funcionales. En el ejemplo con la tarea de Gradle integrationTest se ejecutan los teses de funcionales de Geb.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...

task integrationTest(type: Test) {
    group = 'Verification'
    description = 'Runs the integration/functional tests.'

    // Incluir los teses de integración
    include '**/geb/*Spec.*'
}

...
build-tasks.gradle

Con Gradle el informe de resultados de las pruebas se genera en build/reports/tests/integrationTest en una colección de páginas HTML con el siguiente aspecto. Si hubiese algún error se mostraría un mensaje descriptivo del fallo ocurrido. La prueba IndexSpec tarda medio minuto ya que previamente ha de iniciar el servidor de aplicaciones con la aplicación, en este caso usando Spring Boot.

Informe de pruebas de integración

Informe de las pruebas funcionales

Algunas otras herramientas que son ampliamente usadas en proyectos Java son las que comentaba en el artículo Nueva visita a herramientas para un proyecto Java.

Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
./gradlew integrationTest


Comparte el artículo: