Pasos de prueba
Los pasos de prueba son un mecanismo para el registro estructurado, compatible con la mayoría de los adaptadores de Allure.
Un paso comienza y termina alrededor de un bloque de código, típicamente una función o una función lambda, con el nombre del paso describiendo lo que el código intenta hacer: “Inicializando datos de prueba,” “Conectando al servidor”. A diferencia de una entrada de registro de texto simple que solo puede mostrar un evento único, un paso permite ver los resultados de ejecución de todo el bloque de código. Un paso también puede contener pasos anidados formando una estructura tipo árbol.
En el informe de prueba, Allure muestra los pasos en orden cronológico, preservando la estructura de anidación. Para cada paso, muestra su duración separada, estado y, opcionalmente, parámetros y archivos adjuntos.
¿Por qué usar pasos de prueba?
Usar pasos en tus pruebas tiene dos propósitos: simplificar la depuración de pruebas y mejorar la documentación de las mismas.
Simplificar la depuración de tus pruebas
Al igual que cualquier otra forma de registro, los pasos te ayudan a ver qué secciones del código de prueba se ejecutaron y cuáles no. Pero a diferencia de una entrada de registro tradicional, cada paso es un intervalo, no un instante. Esto te ayuda a encontrar el bloque de código que comenzó pero no terminó exitosamente, juzgando por los estados de los pasos. Esto también es útil al buscar bloques de código que tardan demasiado en ejecutarse, gracias a la duración que se muestra junto a cada paso.
Una vez que identifiques un bloque de código problemático, Allure te ayudará a investigar más a fondo qué ocurrió al proporcionar un completo mensaje de error con el rastreo de la pila.
El informe puede mejorarse aún más agregando adjuntos a los pasos. Una práctica común es registrar el estado de una interfaz gráfica de usuario adjuntando una captura de pantalla en cada paso. Para escenarios de prueba complejos, esto ayudará a entender exactamente dónde ocurrió el problema sin recurrir a pruebas manuales.
Para la mayoría de los lenguajes y marcos de prueba, Allure proporciona una forma de establecer anotaciones especiales (atributos, decoradores) en tus funciones de prueba, convirtiendo automáticamente cada llamada de las funciones en un paso o sub-paso con un esfuerzo mínimo.
Documentar lo que hacen tus pruebas
Una lista de pasos bien descritos sirve como una descripción de alto nivel de una prueba. Esto puede ayudar a tus colegas o gerentes a entender lo que hace sin necesidad de leer el código.
Para lograr esto, recomendamos asegurarse de que los pasos cubran toda la prueba, es decir, que cada línea de código pertenezca a un paso u otro. Si utilizas un framework orientado a BDD como Cucumber o Robot Framework, tu código ya sigue esta regla, y Allure usará automáticamente los pasos del marco. De lo contrario, divide tu código de prueba en pasos de alto nivel tú mismo utilizando funciones o funciones lambda. Opcionalmente, marca algunos eventos importantes durante la prueba utilizando llamadas no operativas.
En pruebas complejas, los pasos de alto nivel suelen ser útiles como documentación, mientras que los pasos de bajo nivel proporcionan información para la depuración.
Pasos creados automáticamente
Siempre que sea posible, Allure Report aprovecha el concepto de un paso proporcionado por el propio marco de prueba.
Por ejemplo, este es el caso con Cucumber-JVM, Behave, SpecFlow y otros frameworks orientados a BDD que utilizan el formato de archivo Gherkin. El adaptador de Allure hace todo lo posible por reflejar la estructura de un archivo Gherkin de la misma manera que lo haría un reportero nativo, al tiempo que permite al autor de la prueba definir sub-pasos arbitrarios en el código de cada paso.
Además, existe una variedad de paquetes de integración que proporcionan la creación automática de pasos en ciertos eventos. Consulta la página de Módulos. En el ejemplo a continuación, los sub-pasos son creados por el paquete de integración de Allure para la biblioteca AssertJ. Existen otros paquetes de integración para bibliotecas de solicitudes HTTP, bibliotecas SQL, etc.
Pasos creados por tu código
Dependiendo de tu lenguaje de programación y framework, Allure puede proporcionar una o más formas de definir pasos de prueba y sub-pasos. Consulta la documentación del adaptador de Allure específico para más detalles.
En general, los estilos compatibles incluyen:
Si tu adaptador de Allure admite varios estilos, puedes usarlos de forma intercambiable en la misma prueba. Por ejemplo, puedes dividir tu prueba en grandes funciones, cada una dividida aún más en sub-pasos lambda, cada uno informando múltiples pasos no operativos.
Pasos como funciones reutilizables
Este enfoque también se conoce como “pasos decorados,” “pasos anotados” o “pasos basados en atributos”. Consiste en declarar una función o método que implemente un paso, marcándola de alguna manera específica del lenguaje (por ejemplo, agregando una anotación especial en Java), y luego llamar a la función una o varias veces durante la ejecución de la prueba.
Usar funciones ayuda a evitar conflictos de nombres entre variables utilizadas en diferentes pasos. Además, esto permite que diferentes pruebas llamen al mismo paso en algún momento, por ejemplo, dos pruebas pueden compartir una rutina de preparación.
Si la función acepta argumentos, algunos adaptadores de Allure los interpretan automáticamente como parámetros de paso.
@Step("Abrir el sitio web")
void openWebsite(String url) {
// ... lógica de navegación del navegador ...
}
Pasos como funciones lambda
Cuando la reutilización de la implementación de los pasos no es una prioridad, puede ser más conveniente definir pasos directamente como funciones lambda. Cuando los pasos individuales son pequeños, este enfoque a menudo conduce a un código de prueba breve y autoexplicativo.
Allure.step("Abrir el sitio web", () -> {
// ... lógica de navegación del navegador ...
});
Pasos como llamadas sin operación (no-op)
A veces puede ser importante reportar un evento instantáneo, similar a cómo un registro de texto incluiría un mensaje de texto. La mayoría de los adaptadores de Allure proporcionan una manera de hacerlo en forma de un “paso sin operación” (no-op step). Este tipo de paso no contiene código ejecutable y nunca tiene sub-pasos.
Tenga en cuenta que cuando se espera que su prueba produzca una gran cantidad de mensajes, puede ser mejor agregarlos al resultado de la prueba como un adjunto de texto en su lugar.
// ... lógica de navegación del navegador ...
Allure.step("Abrir el sitio web");
Fixtures
Un fixture, también conocido como un hook, es un fragmento de código que se ejecuta antes o después de una prueba o un grupo de pruebas. El código que se ejecuta antes de las pruebas a menudo se conoce como una "función de configuración" (setup function), y el código que se ejecuta después de las pruebas como una "función de limpieza" (teardown function).
Para los frameworks de prueba que admiten fixtures, Allure considera cada fixture como un paso separado y lo muestra en un bloque especial encima o debajo de la lista de pasos propios de la prueba. Al igual que un paso normal, un fixture puede dividirse en subpasos.
En algunos adaptadores de Allure, incluir los fixtures en el informe de prueba es opcional y puede deshabilitarse en la configuración. Deshabilitar los fixtures puede ayudar a mantener el informe limpio y legible, pero ten en cuenta que incluir todos los fixtures puede ser útil, por ejemplo, para detectar problemas de tiempo.
Estados de pasos
De manera similar a los estados de las pruebas, cada paso de prueba tiene su propio estado. El estado de un paso no tiene que ser el mismo que el estado de toda la prueba; por ejemplo, puedes tener un paso fallido dentro de una prueba aprobada.
Si un paso se implementa como una función o una función lambda, generalmente se le asigna el estado Pasado si el código se ejecuta normalmente, o el estado Fallido o Roto si lanza una excepción. El comportamiento exacto puede variar según los diferentes adaptadores de Allure.
Si necesitas que la prueba continúe después de que un paso haya lanzado una excepción, captura la excepción fuera del paso, como se muestra en el ejemplo a continuación.
Si un paso es un paso sin operación (no-op), se le asigna el estado Pasado por defecto.
Algunos adaptadores proporcionan una forma de pasar otro estado como un argumento en la API de tiempo de ejecución (Runtime API), consulta la referencia para tu adaptador. Recomendamos usar los mismos significados aproximados de los estados para mantener la consistencia: por ejemplo, utiliza Pasado y Fallido para reportar acciones exitosas y no exitosas, respectivamente.
El ejemplo a continuación muestra cómo los estados de las pruebas pueden ayudar al lector a entender los resultados de la prueba. Aquí, la prueba hizo tres intentos de cargar algunos datos de internet. Los estados de los pasos indican que los dos primeros intentos fallaron, pero el código capturó las excepciones y procedió al tercer intento, que fue exitoso.
Allure.step("Cargar datos del servidor remoto", () -> {
for (int attempt = 1; attempt <= 3; attempt++) {
try {
Allure.step("Intento #%d".formatted(attempt), () -> {
// ... lógica de carga de datos ...
});
break;
} catch (Exception e) {
if (attempt == 3) {
throw e;
}
}
}
});
Allure.step("Validar las cabeceras de respuesta", () -> {
// ... aserciones ...
});
Allure.step("Validar los datos", () -> {
// ... aserciones ...
});
Duración de pasos
Allure Report siempre calcula la diferencia entre el tiempo de inicio y el tiempo de finalización de un paso. El resultado se muestra junto al nombre del paso en el informe de la prueba.
En el ejemplo a continuación, puedes ver de inmediato que los dos primeros pasos pasaron muy rápido, mientras que el tercero falló después de un intervalo de tiempo sospechosamente redondo (casi exactamente tres segundos). Esto suele ocurrir porque alguna operación se interrumpe por un tiempo de espera (timeout) en el código de la prueba o en el código del producto.
Excepciones en pasos
Cuando escribes pasos como funciones reutilizables o funciones lambda, Allure se encarga de registrar cualquier excepción lanzada por las funciones. El mensaje de la excepción y el seguimiento de la pila (stack trace) se adjuntan al paso, y el paso obtiene el estado Fallido o Roto dependiendo del tipo de excepción.
En el ejemplo a continuación, la prueba realiza múltiples intentos de ejecutar algún código, cada uno envuelto en Allure.step()
y luego en un bloque try
. El bloque aquí no procesa errores de aserción (el bloque catch
está vacío) y solo sirve para mantener la prueba en ejecución después de ellos. Sin embargo, la implementación de Allure.step()
se asegura de que el mensaje de la excepción se muestre si haces clic en un paso fallido. (El seguimiento completo de la pila se mostrará si haces clic en el mensaje.)
String[] resolutions = {"1920x1080", "1280x720", "1024x768", "800x600"};
for (String resolution : resolutions) {
try {
Allure.step("Renderizando en " + resolution, () -> {
// ... lógica de renderizado y aserciones ...
});
} catch (AssertionError ignored) {
}
}
Parámetros de pasos
Los parámetros de los pasos son una forma de describir los datos con los que trabajó el paso.
INFO
Esto no debe confundirse con los parámetros de las pruebas que caracterizan toda la prueba.
La API para establecer parámetros de los pasos varía según los diferentes adaptadores de Allure y los diferentes estilos de declaración de pasos. Por ejemplo:
- Para una función de paso reutilizable, algunos adaptadores de Allure muestran automáticamente cada argumento como un parámetro de paso.
- Para un paso lambda, algunos adaptadores de Allure proporcionan un objeto especial que se puede usar para manipular la lista de parámetros desde dentro del paso.
- Para ambos estilos, generalmente es posible especificar manualmente una lista de parámetros de paso llamando a un método especial de la API de tiempo de ejecución (Runtime API).
Para más detalles, consulta la referencia para tu adaptador.
En el ejemplo a continuación, la prueba usa parámetros para describir los perfiles de usuario que crea. El conjunto de parámetros es diferente en cada paso.
Allure.step("Crear usuario Alice", step -> {
step.parameter("Nombre", "Alice");
step.parameter("Login", "alice");
step.parameter("Email", "[email protected]");
// ... lógica de creación de usuario ...
});
// ... otros pasos ...
Archivos adjuntos de pasos
Allure Report admite adjuntar archivos arbitrarios a un paso. Esto se puede usar para describir ya sea los datos de entrada que el paso procesó (similar a los parámetros de paso) o los datos de salida que recibió de algún lugar.
Por ejemplo:
- En una prueba de aplicación de interfaz de usuario (UI), es posible que desees guardar capturas de pantalla de la aplicación después de cada acción.
- En una prueba de aplicación web, es posible que desees guardar todas las solicitudes y respuestas HTTP que realiza la prueba.
- En cualquier tipo de prueba, es posible que desees guardar los registros generados por el sistema bajo prueba.
Adjuntar archivos a los pasos puede ser una forma de contar al lector una historia cronológica, en la que ciertas capturas de pantalla u otros archivos ilustran momentos específicos de la ejecución de la prueba.
Algunos tipos de archivos populares se mostrarán en la página del informe de prueba, otros estarán disponibles para su descarga si el lector hace clic en un enlace. Consulta Archivos adjuntos para más información.
Allure.step("Visitar el sitio web", () -> {
// InputStream screenshot = ...
Allure.attachment("Captura de pantalla de la página principal", screenshot);
});
// ... otros pasos ...
Pasos solo con archivo adjunto
Allure Report admite un caso especial llamado “paso solo con archivo adjunto”. Es un paso que no contiene sub-pasos y contiene exactamente un archivo adjunto con el mismo nombre que el paso en sí. Allure Report simplificará visualmente dicho paso, mostrando solo el archivo adjunto, mientras preserva su posición en relación con otros pasos. Cualquier parámetro para el paso no se mostrará.
En el ejemplo a continuación, el archivo adjunto “Captura de pantalla del formulario completado” está envuelto en el paso “Captura de pantalla del formulario completado”. Esto permite colocar la captura de pantalla después de los pasos anteriores, pero antes del paso posterior.
Allure.step("Visitar el sitio web", () -> {
// ... código de navegación por el navegador ...
});
Allure.step("Captura de pantalla de la página principal", () -> {
// InputStream screenshot = ...
Allure.attachment("Captura de pantalla de la página principal", screenshot);
});
// ... otros pasos ...