Automation: WebDriverWait en lugar de Thread.sleep

Vamos a imaginarnos que estamos ejecutando un test en una aplicación web. El test viene de lo mejor, hasta un determinado momento que nuestro código ejecuta tan rápido los pasos en la página web que hace que no nos encontramos con algún elemento que estemos buscando. Esta es la famosa NoSuchElementException. Para reducir la velocidad de la prueba uno automáticamente piensa en colocar una pausa antes de que se busque por ese elemento. Así que se coloca un bloque similar a este:

try {
    Thread.sleep(5000);
} catch (InterruptedThreadException e) {
    //manejo de la excepción
}

Si ejecutamos la prueba de nuevo, la página espera 5 segundos y luego continúa con el test. Con esto pensamos que se resolvió el problema. Sin embargo, a medida que seguimos codeando tests, escribimos bloques de "Thread.sleep" en todo el código. Al final lo que logramos es un pérdida de tiempo en la ejecución de los tests, debido a estas esperas de 5 segundos.

Entonces, ¿cuál es la solución a este problema? Existe una clase llamada WebDriverWait, que hace lo que necesitamos con un poco de inteligencia. Simplemente, basta especificarle la condición por la que estamos esperando con ExpectedCondition (en nuestro caso esperar por un elemento), y decirle la cantidad  de tiempo límite que debe esperar.

En Selenium 2.6 esta técnica es múy fácil de implementar, sin embargo voy a mostrarles como utilizarla en las versiones anteriores y posteriores a esta.


Versiones anteriores de Selenium 2.06

WebDriverWait wait = new WebDriverWait(driver, 5); // tiempo límite de espera: 5 segundos

// se espera por la condición de que el elemento "ele" esté visible en la página
ExpectedCondition<Boolean> resultsAreDisplayed = new ExpectedCondition<Boolean>() {

    public Boolean apply(WebDriver driver) {
        return driver.findElement(By.id("ele")).isDisplayed();
    }
};

wait.until(resultsAreDisplayed);



Selenium 2.06 y versiones posteriores

Se puede utilizar el código del ejemplo anterior en versiones de Selinum 2.6 y superiores, pero a partir de esta última versión, la clase ExpectedConditions brinda una serie de métodos auxiliares que nos son muchisimos más útiles:
http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html

Entonces, podemos hacer lo mismo que hicimos en el caso anterior, pero utilizando simplemente las siguientes líneas de código:

WebDriverWait wait = new WebDriverWait(driver, 5); // tiempo límite de espera: 5 segundos
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("ele")));


Simple, sencillo, fácil de implementar y mucho más óptimo.

Saludos.

No comments:

Post a Comment