Introducción
Selenium nos permite, entre otras
cosas, grabar pruebas realizadas sobre una aplicación web (las acciones que
hacemos desde el navegador) para reproducirlas y repetirlas en un futuro sin
necesidad de intervención del usuario (o tester).
Ventajas
- Una vez grabado el caso de prueba, si queremos repetirlo, simplemente lo reproducimos desde Selenium. Si por ejemplo un caso de prueba nos implica hacer 15 clicks por pantallas y tardamos N minutos, si lo grabamos con Selenium, no tendremos que repetir el proceso otra vez mecánicamente como si fuésemos "monos", ya se encarga Selenium de reproducirlo las veces que queramos.
- Lo podemos utilizar con otros fines. Por ejemplo, para preparar una demostración en la que queremos pasar por N pantallas, para que no se nos olvide nada (o simplemente como guión).
- Una vez grabados todos los casos de prueba, podemos reproducirlos de golpe para comprobar que tras nuevos cambios que hayamos hecho no se ha estropeado nada (efectos colaterales sobre otras pantallas). Obviamente, habrá que actualizar los casos de prueba (realizando una nueva grabación del caso de prueba o eliminado/insertando pasos) si hemos introducido o eliminado componentes en las pantallas.
Integración de Selenium
- Nos descargamos el Selenium IDE (plugin para Firefox) desde aquí: Download latest released version (http://release.seleniumhq.org/selenium-ide/1.10.0/selenium-ide-1.10.0.xpi)
- Una vez instalado, reiniciamos Firefox y vamos a: Ver -> Panel lateral -> Selenium IDE
El botón de la izquierda es para reproducir los tests y el de la derecha para grabar las interacciones con el navegador (las pruebas que hagamos).
Hacemos un par de clicks sobre la aplicación web con la que estemos trabajando, y grabamos la prueba:
Hacemos un par de clicks sobre la aplicación web con la que estemos trabajando, y grabamos la prueba:
Integración de Selenium con Wicket (Consideraciones "especiales")
Si reprodujésemos el test, tendríamos problemas al trabajar con Wicket, ya que si no se especifica en cada componente el MarkupId, Wicket lo autogenera (diferente en cada nueva reproducción de la prueba, por lo que en no encontraría el componente por variar su id en cada plan de ejecución).
Para subsanar este problema, hacemos lo siguiente:
Para subsanar este problema, hacemos lo siguiente:
- En la clase que tengamos que extienda de WebApplication, sobrescribimos el método init, añadiendo la línea getDebugSettings().setOutputComponentPath(true), que nos sirve para habilitar el atributo"wicketpath" (identificador único).
@Override
protected void init() {
super.init();
getDebugSettings().setOutputComponentPath(true);
}
- Creamos una carpeta "wicketPathLocatorBuilder" (Donde queramos, en D: o donde sea
- Creamos un fichero "user-extension.js.wicketPathLocatorBuilder" con el siguiente contenido, que guardamos en esa carpeta:
this.log.debug("wicketpath: e=" + e);
if (e.attributes && e.hasAttribute("wicketpath")) {
this.log.info("found attribute " + e.getAttribute("wicketpath"));
return "//" + this.xpathHtmlElement(e.nodeName.toLowerCase()) + "[@wicketpath=" + this.attributeValue(e.getAttribute("wicketpath")) + "]";
}
return null;
});
LocatorBuilders.order.unshift(LocatorBuilders.order.pop());
- Vamos a Selenium y seleccionamos la opción Options > Options
- Indicamos la ruta en "Selenium Core extensions"
- Aceptamos y reiniciamos Firefox
Exportando los casos de prueba a scripts
Utilizando "Export Test Case As...":
Podemos exportar los casos de prueba como "scripts" para lanzarlos con Junit, Ruby, C#, ...
Por ejemplo, con Ruby:
Por ejemplo, con Ruby:
Y
el script sería este (al ejecutarlo nos abre automáticamente el
Firefox, lanza la prueba y cuando acaba se cierra y pone los
resultados):
require "selenium-webdriver"
gem "test-unit"
require "test/unit"
class Papidal < Test::Unit::TestCase
def setup
@driver = Selenium::WebDriver.for :firefox
#@base_url = "http://localhost:8090/"
@accept_next_alert = true
@driver.manage.timeouts.implicit_wait = 30
@verification_errors = []
end
def teardown
@driver.quit
assert_equal [], @verification_errors
end
def test_papidal
@driver.get("http://localhost:8090/myproject/")
@driver.find_element(:xpath, "//a[@wicketpath='showModalLink']").click
end
def element_present?(how, what)
@driver.find_element(how, what)
true
rescue Selenium::WebDriver::Error::NoSuchElementError
false
end
def verify(&blk)
yield
rescue Test::Unit::AssertionFailedError => ex
@verification_errors << ex
end
def close_alert_and_get_its_text(how, what)
alert = @driver.switch_to().alert()
if (@accept_next_alert) then
alert.accept()
else
alert.dismiss()
end
alert.text
ensure
@accept_next_alert = true
end
end
gem "test-unit"
require "test/unit"
class Papidal < Test::Unit::TestCase
def setup
@driver = Selenium::WebDriver.for :firefox
#@base_url = "http://localhost:8090/"
@accept_next_alert = true
@driver.manage.timeouts.implicit_wait = 30
@verification_errors = []
end
def teardown
@driver.quit
assert_equal [], @verification_errors
end
def test_papidal
@driver.get("http://localhost:8090/myproject/")
@driver.find_element(:xpath, "//a[@wicketpath='showModalLink']").click
end
def element_present?(how, what)
@driver.find_element(how, what)
true
rescue Selenium::WebDriver::Error::NoSuchElementError
false
end
def verify(&blk)
yield
rescue Test::Unit::AssertionFailedError => ex
@verification_errors << ex
end
def close_alert_and_get_its_text(how, what)
alert = @driver.switch_to().alert()
if (@accept_next_alert) then
alert.accept()
else
alert.dismiss()
end
alert.text
ensure
@accept_next_alert = true
end
end
Si
queremos lanzarlo con Internet Explorer, simplemente nos aseguramos que el zoom del
navegador esté al 100% (o nos dará un error del estilo "browser zoom
level was set to 104%. It should be set to 100%"). Para ello ajustamos
el IE pulsando Ctrl+Scroll (menuda frikada :)).
Además, en el caso de ruby con IE, simplemente sería cambiar el Driver, poniendo esta línea:
@driver = Selenium::WebDriver.for :ie
Y añadiendo al PATH (variable de entorno) el fichero: IEDriverServer.exe, que descargaremos de una de estas dos rutas:
Download version 2.30.2 for (recommended) 32 bit Windows IE or 64 bit Windows IE (http://code.google.com/p/selenium/downloads/detail?name=IEDriverServer_x64_2.30.2.zip)
Como en casa tengo un equipo de 64 bits, me bajé la segunda opción.
El resultado al lanzar el script, sería la apertura automática del IE ejecutando los tests y al acabar se cerraría sólo mostrando por consola esta traza:
Además, en el caso de ruby con IE, simplemente sería cambiar el Driver, poniendo esta línea:
@driver = Selenium::WebDriver.for :ie
Y añadiendo al PATH (variable de entorno) el fichero: IEDriverServer.exe, que descargaremos de una de estas dos rutas:
Download version 2.30.2 for (recommended) 32 bit Windows IE or 64 bit Windows IE (http://code.google.com/p/selenium/downloads/detail?name=IEDriverServer_x64_2.30.2.zip)
Como en casa tengo un equipo de 64 bits, me bajé la segunda opción.
El resultado al lanzar el script, sería la apertura automática del IE ejecutando los tests y al acabar se cerraría sólo mostrando por consola esta traza:
Exportando los casos de prueba de Selenium con Junit
Si preferimos exportar el caso de prueba con Junit, para poder lanzarlo cómodamente desde Eclipse, necesitaremos algunas dependencias adicionales. Según el navegador que deseemos usar, modificaremos a nuestro gusto la dependencia "selenium-firefox-driver", en este caso, nos permitirá lanzar nuestros tests contra Firefox:<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.29.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>2.29.1</version>
</dependency>
Además, para evitar otros errores al ejecutar el test, necesitaremos la siguiente versión de "xml-apis":
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
Selenium, provee los drivers para dar soporte con Safari, IE, Firefox, … Con lo que podemos comprobar si nuestras pruebas funcionan en los distintos navegadores (compatibilidad). En este ejemplo me centro en Firefox, pero en teoría sólo hay que cambiar la clase del driver del navegador que queremos que ejecute el test.
Con JUNIT, con el servidor en local levantado en el puerto 8080, al lanzar el test se abrirá automáticamente el Firefox y en él se ejecutará el caso de prueba (navegando él sólo por las pantallas que le hemos indicado). Al finalizar, si no hubo errores, se cierra el navegador sólo y tendremos el test en "verde".
File file = new File("D:\\util\\IEDriverServer.exe");//El path que sea
System.setProperty("webdriver.ie.driver", file.getAbsolutePath());
driver = new InternetExplorerDriver();
Otras consideraciones
En ocasiones, el "wicketpath" no es suficiente, y para algún elemento puede ser necesario setear los siguientes atributos:botonFiltro.setMarkupId("filtro1");
botonFiltro.setOutputMarkupId(true);
Se aconseja encarecidamente configurar el orden de los localizadores en el plugin de Selenium de la siguiente forma (según necesidades):
Si es posible que tarde unos segundos una pantalla hasta que se cargue, le damos tiempo a que se cargue la página, con la función isElementPresent. Cuando nos devuelva true, sabemos que ya está cargada la pantalla con el elemento que queremos usar para la prueba. Ejemplo:
//...
driver.findElement(By.xpath("//div[@id='bigPageLinks']/ul/li[3]/form/a")).click();
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (isElementPresent(By.cssSelector("#modelo"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
driver.findElement(By.cssSelector("#modelo")).clear();
driver.findElement(By.cssSelector("#modelo")).sendKeys("8032");
//...