Introducción a Selenium 2 y WebDriver
Índice de contenidos.
- 1. Introducción
- 2. Entorno
- 3. Crear un proyecto de pruebas
- 4. Crear un test básico
- 5. Explorando el API para interactuar con la página HTML
- 6. Conclusiones
1. Introducción
Selenium es un conjunto de herramientas para automatizar test en aplicaciones web con las que poder grabar, configurar, lanzar y comprobar que nuestras aplicaciones web hacen lo que realmente deben hacer. Continuando con nuestros tutoriales sobre testing y concretamente con pruebas con Selenium, en esta ocasión veremos las novedades que trae la versión 2.
Algunas de las nuevas características a destacar son:
- Inclusión de WebDriver dentro de Selenium. La principal contribución de WebDriver son los controladores nativos que dan soporte a distintos navegadores (Internet Explorer, Firefox, Chrome y próximamente Opera y Safari). Debido a que Selenium tiene las restricciones propias del Javascript (lenguaje con el que está hecho), WebDriver va más allá y dependiendo del navegador que queramos probar utiliza el mecanismo más apropiado, por ejemplo en Firefox se implementa como una extensión, para Internet Explorer hace uso de los objetos propios de automatización. Incluso puede hacer uso de las características de los navegadores desde el punto de vista del sistema operativo. Gracias a WebDriver ya no necesitamos de un navegador web real para lanzar los test sino que utiliza una aplicación basada en HtmlUnit para simular el navegador. A partir de la versión 2 de Selenium disponemos de toda la funcionalidad que teníamos hasta ahora y adicionalmente, si la necesitamos, las capacidades de WebDriver.
- Permite test de Selenium en dispositivos móviles iPhone y Android. Cada vez son más populares este tipo de dispositivos por lo que Selenium 2 incluye un emulador para poder testear las aplicaciones.
- Dispone de una API más sencilla. Una simplificación del interfaz con dos clases principales: WebDriver (para el control de los distintos navegadores) y WebElement (para los elementos que componen la página web).
- Arquitectura mejorada. La nueva arquitectura introduce una seria de características para facilitar la realización de los test: incluye un teclado nativo, soporte a eventos de ratón, manejo de popups, frames, etc.
- Conexión remota a navegadores en otras máquinas por si en el entorno de pruebas no se dispusiera de ellos.
- Ejecución de Javascript, acceso al objeto Window, temporizadores, clases con funcionalidad básica para facilitar los test, etc.
- Compatibilidad de los test de Selenium en JUnit a la nueva API de WebDriver a través de la clase WebDriverBackedSelenium
2. Entorno
- MacBook Pro 15′ (2.4 GHz Intel Core i5, 4GB DDR3 SDRAM).
- Sistema Operativo: Mac OS X Snow Leopard 10.6.6
- Java 1.6.0_22
- Maven 3.0.2
- Selenium 2.0 Beta 2
- JUnit 4.8.2
3. Crear un proyecto de pruebas
Para empezar las pruebas lo primero que debemos tener es un proyecto por lo que usaremos maven para crear uno. Para ello utilizamos un arquetipo mediante el comando mvn archetype:generate. Concretamente utilizaremos el archetipo 101 que nos creará una proyecto maven estándar.
Una vez creado el arquetipo del proyecto abrimos el pom.xml y añadimos la dependencia del selenium-server. Selenium-server a su vez tiene las dependencias al selenium-htmlunit-driver, selenium-ie-driver, selenium-firefox-driver, selenium-chrome-driver, selenium-iphone-driver, etc. Si no se ve necesaria la inclusión de alguna de estas librerías se pueden excluir aunque como estas dependencias están con el scope de test no pasa nada porque nos las incluya. De paso actualizamos la versión de JUnit a la 4.8.2 en el pom.xml
org.seleniumhq.selenium selenium-server 2.0b2 test junit junit 4.8.2 test
4. Crear un test básico
Un primer test para irnos familiarizando con el API sería conectarnos a la web de AdictosAlTrabajo y comprobar que llegamos a ella, por ejemplo comprobando el título de la página:
public class SeleniumTest { private WebDriver driver; @Before public void setUp() { driver = new HtmlUnitDriver(); } @After public void tearDown() { driver.close(); } @Test public void connectToAdictos() { driver.get("https://adictosaltrabajo.com"); Assert.assertEquals("Adictos al Trabajo. Formación y desarrollo | JAVA, JEE, UML, XML |. Tutoriales sobre nuevas tecnologías.", driver.getTitle()); } }
El código resultante del test es sencillo, basta con crear una instancia del driver correspondiente que hace las veces de motor o controlador del navegador. En este caso para no tener necesidad de utilizar un navegador se ha utilizado el HtmlUnitDriver que es un simulador de un navegador en memoria. Utilizando el método get le decimos que se conecte al dominio indicado y posteriormente comprobamos que el título es el esperado mediante un método assert.
Recordar que si en la máquina donde se lancen los test no está instalado un navegador de los soportados por WebDriver y en un test se utiliza el driver de ese navegador, el test fallará. Por ejemplo si en un Mac lanzamos un test que utilice el InternetExplorerDriver (sólo disponible desde Windows), este test fallará debido a que el driver no encontrará este programa instalado en el sistema operativo dando el siguiente error: org.openqa.selenium.WebDriverException: java.io.IOException: Unable to locate: IEDriver.dll. Por ello es importante tener en cuenta el entorno de ejecución de los test. Para solucionar este problema se puede lanzar el test contra un servidor remoto que sí tenga instalado el sistema operativo. Esto lo veremos en futuros tutoriales.
Si lo que queremos es probar nuestra aplicación desde un entorno no Windows pero con el driver de InternetExplorer tambié se le puede indicar al HtmlUnitDriver que simule este navegador con la versión que queramos:
final WebDriver driver = new HtmlUnitDriver(BrowserVersion.INTERNET_EXPLORER_6);
5. Explorando el API para interactuar con la página HTML
Hemos visto hasta ahora la introducción a Selenium 2 que incluye el API WebDriver y hemos creado un proyecto de test. Hasta hemos hecho nuestro primer test sencillo de conexión a una página web. Ahora vamos a mostrar un poco más las opciones de este API para las pruebas de aplicaciones web.
En el test anterior utilizamos la clase WebDriver que nos da soporte para conectarnos a nuestra aplicación web. Una vez que nos conectamos podemos interactuar con la página y los distintos elementos que la componen: elementos de un formulario, enlaces, capas, etc:
Para interactuar con la caja de texto hay múltiples formas, desde buscarla dentro del DOM por nombre (name), por identificador (id), selector css indicado explicitamente por el atributo (class), selector css aplicable al componente (input.clase), nombre de etiqueta (input), etc. Para las pruebas con la página de Google el código quedaría asi:
Para interactuar con esta caja de texto podemos utilizar cualquiera de las siguientes opciones:
@Test public void connectToGoogle() { final WebDriver driver = new HtmlUnitDriver(); driver.get("http://www.google.es"); Assert.assertEquals("Google", driver.getTitle()); // WebElement webElementById = driver.findElement(By.name("q")); WebElement webElementByClassName = driver.findElement(By.className("lst")); WebElement webElementByCssSelector = driver.findElement(By.cssSelector("input[name=\"q\"]")); WebElement webElementByTagName = driver.findElement(By.tagName("input")); WebElement webElementByXPath = driver.findElement(By.xpath("//*[@name=\"q\"]")); }
Una vez que accedemos a los elementos de la página podemos rellenar los campos de texto, cambiar los valores de los combos, hacer click en los botones, etc. Se muestra a continuación un ejemplo de uso de cómo se rellena un formulario:
El formulario en cuestión:
El código del test que prueba el formulario se encarga de meter los datos en el mismo, llamar al método que hace el click del botón y capturar el alert comprobando que el mensaje es el correcto. Para las pruebas he metido el código de este tutorial en un servidor apache.
@Test public void fillForm() throws UnknownHostException { final WebDriver driver = new FirefoxDriver(); driver.get("http://" + InetAddress.getLocalHost().getHostAddress() + "/~jalonso/selenium/Selenium2.html"); final String OPTION_MADRID = "Madrid"; driver.findElement(By.id("nombre")).sendKeys("Juan"); driver.findElement(By.id("apellidos")).sendKeys("Alonso"); driver.findElement(By.id("email")).sendKeys("jalonso@autentia.com"); final List<WebElement> options = driver.findElements(By.tagName("option")); for (WebElement option : options) { if (option.getText().equals(OPTION_MADRID)) { option.setSelected(); } } final List<WebElement> radios = driver.findElements(By.name("newsletters")); for (WebElement radio : radios) { if (radio.getValue().equals("true")) { radio.setSelected(); } } driver.findElement(By.id("enviar")).click(); final Alert alert = driver.switchTo().alert(); if (!alert.getText().equals("OK")) { Assert.fail(alert.getText()); } }
Mediante el método switchTo del driver podemos posicionarnos en los distitos objetos que componen la página web: alert, frame, window, history, cookies. Es importante destacar que el HtmlUnitDriver no soporta el método alert.
HtmlUnit no utiliza el mismo motor JavaScript y la interpretación del DOM que el resto de navegadores por lo que los resultados de las pruebas podrían no ser iguales. Esta interpretación, aunque sigue el estándar marcado por el W3C, tiene sus propias peculiaridades como los demás navegadores. Por defecto el HtmlUnitDriver tiene el JavaScript deshabilitado por lo que para habilitarlo bastaría con llamar a este constructor public HtmlUnitDriver(boolean enableJavascript) o bien utilizar el método driver.setJavascriptEnabled(true);
6. Conclusiones
Una vez más hacemos especial incapié en las pruebas de software. En este caso las pruebas de integración o validación se pueden realizar con Selenium que en su versión 2, a fecha de hoy aún en fase beta, no deja de superarse.
Si la aplicación es especialmente complicada siempre se pueden grabar los test con Selenium IDE y exportar posteriormente a código Java (Junit4) para facilitarnos la tarea de realización del test. Ojo ya que el código que nos genera por defecto es con sintaxis Selenium por lo que será necesario instalar esta extensión que sirve para generar el test con API WebDriver.
Espero que te haya sido de ayuda.
Un saludo. Juan.
Gracias. Es muy ilustrativo.
Por favor, necesitaría algo parecido para testear con iphone!!!. Soy tester con un nivel básico de programación. He utilizado bastante selenium IDE y lo he exportado a eclipse. Sin embargo, aunque hay bastante documentación en ingles no consigo comprender como poder testear una aplicación con el iphone (creo que hay que bajarse el iphone driver). Creo que hay un simulador del iphone que se puede también integrar con eclipse para automatizar el testeo de aplicaciónes.
Gracias de nuevo
Hola Juan!
Muy completo el texto sobre las pruebas con selenium muestras muy bien sus capacidades :).
Pero existe un problema con el manejo de alert de javascript, ya el el driver de Internet Explorer no lo soporta :(.
Ahora si conoces de alguna solucion a ese problema te agradeceria me la indicaras 🙂
Gracias
Buenas,
Una pregunta, ¿ Cómo puedo hacer para lanzar el test en diferentes versiones de navegadores ?
IE7, IE8 e IE9, por ejemplo. Si instalas una de esas colecciones que te vienen varias versiones de un navegador, ¿ Se podría elegir en el driver la versión de este?
Muchas gracias.
Estimado, muchas gracias por todas las explicaciones brindadas, Estoy teniendo un problema a la hora de interactuar con el popUp de autentificación de windows, el cual me pide usuario y contraseña, y no logro colocar dichas credenciales. Si o si tengo que utilizar InternetExplorer ya sea 8 u 11.
Desde ya muchas gracias.