Lanzando test distribuidos con Selenium Grid (parte II)

En el post anterior, junto a mi compañera Sabrina, explicamos qué nos puede aportar Selenium Grid para la automatización de pruebas de regresión de nuestras aplicaciones. Hoy vamos a ponerlo en práctica con un ejemplo sencillo.

En el anterior post, ya estuvimos explicando cómo descargar e instalar Selenium Grid, lanzar un hub y registrar un nodo en el mismo con 5 instancias de Firefox, 1 de Safari y 5 de Chrome. Hoy os mostraremos cómo instalar, configurar y ejecutar un set de pruebas en Selenium Grid.

Configuración

Antes de seguir, necesitaremos añadir servidores standalone que implementen el protocolo de WebDriver para cada uno de los navegadores en los que vayamos a ejecutar nuestras pruebas. Para ello copiaremos a la carpeta en la que tenemos el servidor de Selenium, los ejecutables de dichos servidores standalone. En nuestro caso, añadiremos el ChromeDriver para Chrome, GekoDriver para Firefox e IEDriverServer para nuestro Internet Explorer. 

Es requisito indispensable tener una versión de chromedriver.exe que sea compatible con nuestro Chrome. En nuestro caso, usaremos la versión 71 de Chrome, para lo que necesitaremos una versión de 2.41 o superior. Para más información de compatibilidad de navegadores puedes acceder aquí.

También necesitaremos agregar un archivo JSON en el cual configuraremos los navegadores y nuestra máquina. Este es el contenido del fichero configNode.json para el ejemplo:

{
	"capabilities": [
            {
               "browserName": "firefox",
               "firefox_binary": "C:/Program Files (x86)/firefoxes/Mozilla Firefox/firefox.exe",
               "marionette": "true",
               "version": "52",
               "platform": "VISTA",
               "maxInstances": 5,
               "seleniumProtocol": "WebDriver"
            },
             {
               "browserName": "chrome",
               "version": "71",
               "platform": "VISTA",
               "maxInstances": 5,
               "seleniumProtocol": "WebDriver"
            },
            {
               "browserName": "internet explorer",
               "platform": "VISTA",
               "maxInstances": 1,
               "seleniumProtocol": "WebDriver"
            }
  ],
      "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
      "maxSession": 5,
      "port": 5555,
      "register": true,
      "registerCycle": 5000,
      "hub": "http://15.30.170.123:4444",
      "nodeStatusCheckTimeout": 5000,
      "nodePolling": 5000,
      "role": "node",
      "unregisterIfStillDownAfter": 60000,
      "downPollingLimit": 2,
      "debug": false,
      "servlets": [],
      "withoutServlets": [],
      "custom": {}
}

Finalmente, la carpeta de configuración quedará de la siguiente forma:

2-1

Arrancando Grid Console

Como hemos visto anteriormente, en el fichero de configuración hemos registrado una máquina como nodo para que el hub la pueda reconocer como disponible cuando se ejecuten los tests.

Llegados a este punto, podemos arrancar el servidor Selenium ejecutando la siguiente sentencia que apunta a nuestro configNode.json:

java -Dwebdriver.chrome.driver=chromedriver.exe -Dwebdriver.gecko.driver=geckodriver.exe -Dwebdriver.ie.driver=IEDriverServer.exe -jar selenium-server-standalone.jar -role node -nodeConfig configNode.json

 

Podemos verificar que el nodo se ha registrado correctamente accediendo a la consola de Grid desde el navegador:

 http://localhost:4444/grid/console


5

 

Se puede observar que se ha registrado el nodo en el hub y tiene 5 instancias de Firefox, 1 de Safari y 5 de Chrome. Si quisiéramos añadir más nodos, sería suficiente con ejecutar el mismo comando apuntando a otro puerto e indicando el nombre del navegador que queremos. Es decir:  

java -jar selenium-server-standalone.jar -role webdriver -hub http://IP:4444/grid/register -browser browserName=navegador –port 5567

 4-2

 

Implementarción del caso de prueba

Una vez tenemos arrancada nuestra consola de Grid, el siguiente paso será implementar un caso de pruebas para ejecutarlo en aquellos navegadores en los que queramos probar. En este caso, realizaremos una búsqueda en el portal de Google y probaremos en Firefox, Chrome e IE.

Comenzamos creando nuestro proyecto Spring Boot en https://start.spring.io/ y añadimos la dependencia de Selenium al pom.xml del proyecto:

dependenciesgird
Para implementar nuestro caso de pruebas usaremos un test parametrizable: un concepto que se introdujo con JUnit 4 y que, básicamente, nos va a permitir ejecutar múltiples casos con el mismo código, pero con diferentes parámetros. Esto nos permitirá ejecutar el mismo código de prueba y usar dichos parámetros para especificar con qué navegador queremos testearla.

TestGoogleSearch.java:

package es.softtek.selenium;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import junit.framework.TestCase;

@RunWith(Parameterized.class)
public class TestGoogleSearch extends TestCase {
	
	private static final String baseURL = "http://www.google.com";
	private static final String hubRemoteAddress = "http://15.30.170.123:4444/wd/hub";
	private static final String webDriverProperty = "webdriver.ie.driver";

	private WebDriver driver;
	private String browser;
	
	@SuppressWarnings("rawtypes")
	@Parameters
	public static Collection browserData() {
		return Arrays.asList("googlechrome", "iexplore", "firefox");
	}

	public TestGoogleSearch(String browser) {
		this.browser = browser;
	}

	@Before
	public void setUp() throws Exception {
		driver = getWebDriver(this.browser);
	}

	@Test
	public void googleSearch() {

		driver.get(baseURL);
		driver.findElement(By.xpath("//input[@class='gLFyf gsfi']")).sendKeys("Hello selenium grid!!!!");
		driver.findElement(By.xpath("//input[@class='gLFyf gsfi']")).sendKeys(Keys.ENTER);
	}

	@After
	public void tearDown() throws Exception {
		driver.close();
	}

	private static WebDriver getWebDriver(String browser) throws Exception{

		Capabilities capabilities = null;
		if (browser.equals("firefox")) {
			System.setProperty(webDriverProperty, "lib/geckodriver.exe");
			capabilities = new FirefoxOptions();
		}else if (browser.equals("googlechrome")) {
			System.setProperty(webDriverProperty, "lib/chromedriver.exe");
			capabilities = new ChromeOptions();
		}else if (browser.equals("iexplore")) {
			System.setProperty(webDriverProperty, "lib/IEDriverServer.exe");
			capabilities = new InternetExplorerOptions();
		}else {
			throw new Exception("Invalid browser");
		}
		return new RemoteWebDriver(new URL(hubRemoteAddress), capabilities);
	}
}

 

Utilizaremos @RunWith(Parameterized.class) para indicar a JUnit que queremos lanzar un test parametrizable. Para especificar dichos parámetros, en este caso los navegadores, decoraremos el método browserData() con la anotación @Parameters.

Volviendo al test, antes de ejecutar cada caso de prueba debemos obtener el driver del navegador que queremos usar. Para ello tenemos el método setUp(), que decoramos con la anotación @Before para que se ejecute antes de cada caso de prueba, y que . delega en el método getWebDriver() para obtener el driver correspondiente. De la misma forma, en el método tearDown(), que decoramos con la anotación @After, cerraremos el navegador al finalizar cada caso de prueba.

Por último, y no menos importante, el método googleSearch() decorado con @Test contiene la implementación de nuestra prueba, que no es más que abrir la página de Google en el navegador, teclear un texto en el input de búsqueda y pulsar intro para realizar la búsqueda.

 

Ejecución del caso de prueba

Para finalizar, lanzamos nuestro Test usando JUnit y obtenemos los siguientes resultados:

1. Resultado ejecución Chrome:

 11

 

 2. Resultado ejecución IExplorer:


8

 

3. Resultado Firefox (después de intro en navegador) :

9

 

Como hemos comprobado, nuestra consola de Grid nos indicará los que se están utilizando y los que no.

 

 13

 

Conclusiones

Con todo ello, podemos concluir que gracias a Selenium Grid es posible ejecutar nuestros tests en diferentes máquinas contra diferentes navegadores, de manera simultánea y en paralelo. 

En próximos posts veremos cómo podemos combinar esta práctica con el uso de contenedores Docker y despliegue en Cloud para facilitar la escalabilidad y aumentar aún más el rendimiento de nuestras pruebas, ejecutando los test de manera remota.