Cambiar el thread.sleep para no tener deuda técnica
Buenas lectores.
Siempre en nuestras automatizaciones nos encontramos con el problema que el robot cuando se ejecuta va muy rápido, esto ocasiona que los test fallen. En esta situación necesitamos que el robot espere algún elemento para poder continuar la ejecución de forma correcta. Existen muchas formas de poder lograrlo, aquí algunos ejemplos usando SerenityBDD:
Con screenplay:
Ejemplo 1:
jadcode.attemptsTo(WaitUntil.the(LocationForm.BTN_CREATE,isVisible()).forNoMoreThan(2).seconds(),
Click.on(LocationForm.BTN_CREATE));
Ejemplos 2:
jadcode.attemptsTo(Click.on(LocationForm.BTN_CREATE).afterWaitingUntilEnabled());
jadcode.attemptsTo(Click.on(LocationForm.BTN_CREATE).afterWaitingUntilPresent());
Ejemplo 3:
jadcode.attemptsTo(Click.on(LocationForm.BTN_CREATE.waitingForNoMoreThan(Duration.ofSeconds(2))));
Con pageobject:
Ejemplo 1:waitForPresenceOf("//h2[.='A title that is not immediately visible']");
Ejemplo 2:
waitFor("//h2[.='A title that is not immediately visible']");
Ejemplo 3:
WebElement.waitUntilVisible()
Ejemplo 4:
withTimeoutOf(2, SECONDS).waitForPresenceOf(By.cssSelector("#elements option"))
Tambien podemos usar selenium directamente de la siguiente manera:
WebDriverWait wait = new WebDriverWait(Serenity.getDriver(),Duration.ofSeconds(3));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(text(),'COMPOSE')]")));
El problema radica cuando necesitamos esperar pero sin un objeto referencia, cuando esto sucede normalmente recurrimos al famoso:
Thread.sleep(2000);
Esto hace que el robot espere 2 segundos (aclaro que el uso de tiempos desde selenium nunca me han servido, en cambio el Thread.sleep es infalible).
Es muy util cuando no tenemos objetos referencias como por ejemplo, esperar una carga de archivos que no tiene mensaje de confirmación, un refresco de un iframe para evitar que arroje errores de estados entre otros. Sin embargo, cuando pasamos el sonar nos arroja la siguiente deuda técnica:
"Thread.sleep" should not be used in tests
Para solucionar esto, simplemente podemos reemplazar el Thread.sleep por:
"Thread.sleep" should not be used in tests
Para solucionar esto, simplemente podemos reemplazar el Thread.sleep por:
import org.awaitility.Awaitility;
import org.awaitility.Durations;
Awaitility.await().pollDelay(Durations.TWO_SECONDS).until(() -> true);
Con esto hemos logrado mejorar el código y evitar la deuda técnica.
Con esto hemos logrado mejorar el código y evitar la deuda técnica.
Cabe anotar que el pull máximo es de 1 minuto, si queremos superar ese tiempo la sentencia cambia a la siguiente forma:
Awaitility.await().atMost(2, TimeUnit.MINUTES).pollDelay(1, TimeUnit.MINUTES).until(() -> true);
Para tiempos mayores a 5 minutos se debe usar:
Awaitility.await().with().pollInterval(Durations.ONE_SECOND).await().atMost(Durations.TEN_SECONDS).until(myFunction());
Espero les sirviera de algo los tiempos.
Cordial saludo
Fuentes:
https://serenity-bdd.github.io/docs/screenplay/screenplay_webdriver
https://rules.sonarsource.com/java/RSPEC-2925
Fuentes:
https://serenity-bdd.github.io/docs/screenplay/screenplay_webdriver
https://rules.sonarsource.com/java/RSPEC-2925
https://www.browserstack.com/guide/wait-commands-in-selenium-webdriver#:~:text=Implicit%20Wait%20directs%20the%20Selenium,which%20the%20browser%20is%20open.
https://stackoverflow.com/questions/15938538/how-can-i-make-a-junit-test-wait/51650781#51650781
https://stackoverflow.com/questions/51418237/awaitility-in-java
Comentarios
Publicar un comentario