Referencia de Allure JUnit 5
Estas son las funciones que puedes usar para integrar tus pruebas de JUnit 5 con Allure.
Allure JUnit 5 proporciona más de una forma de usar algunas características. En la mayoría de los casos, una forma implica usar una anotación en el método de prueba, mientras que la otra implica una llamada de método dentro del cuerpo del método de prueba. Este último estilo se llama “dinámico” y permite construir valores de forma dinámica.
Metadatos
Asigna la descripción, enlaces y otros metadatos de una prueba.
Title
@DisplayName(String value)
Allure.getLifecycle().updateTestCase(Consumer<TestResult> update)
Establece el título de la prueba.
A diferencia de la mayoría de las funciones descritas aquí, la anotación @DisplayName
es parte de JUnit 5.
Si necesitas construir dinámicamente el título de una prueba, escribe una función lambda que lo haga y pásala al método updateTestCase()
del objeto AllureLifecycle
, consulta el ejemplo a continuación.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
@DisplayName("Test Authentication")
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.getLifecycle().updateTestCase(result -> {
result.setName("Test Authentication");
});
// ...
}
}
Description
@Description(String value="", boolean useJavaDoc=false)
Allure.description(String description)
Establece la descripción de la prueba.
Usa la anotación @Description()
para establecer una descripción de forma estática o usa el método description()
para establecerla dinámicamente en tiempo de ejecución.
import io.qameta.allure.Description;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
@Description("This test attempts to log into the website using a login and a password. Fails if any error happens.\n\nNote that this test does not test 2-Factor Authentication.")
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.description("This test attempts to log into the website using a login and a password. Fails if any error happens.\n\nNote that this test does not test 2-Factor Authentication.");
// ...
}
}
Alternativamente, puedes dejar que Allure JUnit 5 analice la descripción del comentario JavaDoc del método de prueba. Para ello, primero agrega un procesador de anotaciones especial a la configuración de Maven o Gradle de tu proyecto.
// In the project's `build.gradle.kts`
val allureVersion = "2.24.0"
dependencies {
// ...
testAnnotationProcessor("io.qameta.allure:allure-descriptions-javadoc:$allureVersion")
}
Luego, usa la API de Anotaciones con el argumento useJavaDoc=true
en los métodos de prueba para los cuales deseas analizar la descripción desde JavaDoc. Ten en cuenta que en un proyecto grande, procesar las anotaciones puede aumentar significativamente tanto el tiempo de compilación como el tamaño de los archivos ejecutables de prueba.
Se permite el formato Markdown. Cualquier formato HTML, si está presente, será eliminado por razones de seguridad.
import io.qameta.allure.Description;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
/**
* This test attempts to log into the website using a login and a password. Fails if any error happens.
* <p>
* Note that this test does not test 2-Factor Authentication.
*/
@Test
@Description(useJavaDoc = true)
void testAuthentication() {
// ...
}
}
Owner
@Owner(String value="")
Establece el propietario de la prueba.
import io.qameta.allure.Owner;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
@Owner("John Doe")
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.label("owner", "John Doe");
// ...
}
}
Tag
@Tag(String value)
@Tags(Tag[] value)
Establece los tags de la prueba.
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
@Tag("NewUI")
@Tag("Essentials")
@Tag("Authentication")
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.label("tag", "NewUI");
Allure.label("tag", "Essentials");
Allure.label("tag", "Authentication");
// ...
}
}
Severity
@Severity(SeverityLevel value)
Establece la severidad de la prueba.
Los valores permitidos son: “trivial”, “minor”, “normal”, “critical”, y “blocker”.
import io.qameta.allure.Severity;
import org.junit.jupiter.api.Test;
import static io.qameta.allure.SeverityLevel.*;
class TestMyWebsite {
@Test
@Severity(CRITICAL)
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.label("severity", "critical");
// ...
}
}
Label
@LabelAnnotation(String name, String value=DEFAULT_VALUE)
Allure.label(String name, String value)
Establece una etiqueta arbitraria para la prueba. Esta es la implementación subyacente para muchas de las otras funciones de Allure.
Para establecer una etiqueta dinámicamente, simplemente llama a la función label()
con un nombre y un valor para la etiqueta. Puedes hacerlo varias veces para crear un array de valores bajo ese nombre.
Otra forma de establecer una etiqueta es crear una clase personalizada usando @LabelAnnotation
y anotar las pruebas con la nueva anotación, consulta el ejemplo a continuación. Ten cuidado de copiar @Retention
, @Target
y las demás anotaciones necesarias tal como se muestra en el ejemplo, de lo contrario tu anotación personalizada puede no funcionar correctamente.
import io.qameta.allure.LabelAnnotation;
import org.junit.jupiter.api.Test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@LabelAnnotation(name = "CustomLabelName")
@interface MyLabel {
String value();
}
class TestMyWebsite {
@Test
@MyLabel("custom label value")
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.label("language", "java");
Allure.label("framework", "junit5");
Allure.label("CustomLabelName", "custom label value");
// ...
}
}
Allure ID (Allure TestOps)
@AllureId(String value)
Establece el ID de la prueba.
import io.qameta.allure.AllureId;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
@AllureId("123")
void testAuthentication() {
// ...
}
}
Link
@Link(String value="", name="", String url="", String type=CUSTOM_LINK_TYPE)
@Links(Link[] value)
@Issue(String value="")
@Issues(Issue[] value)
@TmsLink(String value="")
@TmsLinks(TmsLink[] value)
Allure.link(String url)
Allure.link(String name, String url)
Allure.link(String name, String type, String url)
Allure.issue(String name, String url)
Allure.tms(String name, String url)
Agrega un enlace relacionado con la prueba.
Según el type
(que puede ser cualquier cadena), Allure intentará cargar un patrón de enlace correspondiente para procesar la URL, como se define en la opción de configuración allure.link.*.pattern
. Si no se encuentra ningún patrón para el tipo dado, la URL se deja sin modificar.
El name
se usará como el texto del enlace. Si se omite, se usará la URL sin procesar.
Para comodidad, Allure proporciona dos funciones abreviadas con tipos de enlace preseleccionados: issue()
y tms()
. Para establecer una etiqueta dinámicamente, simplemente llama a la función label()
con un nombre y un valor para la etiqueta. Puedes hacerlo varias veces para crear un array de valores bajo ese nombre.
import io.qameta.allure.Issue;
import io.qameta.allure.Link;
import io.qameta.allure.TmsLink;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
@Link(name = "Website", url = "https://dev.example.com/")
@Issue("AUTH-123")
@TmsLink("TMS-456")
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.link("Website", "https://dev.example.com/");
Allure.issue("AUTH-123", "https://jira.example.org/browse/AUTH-123");
Allure.tms("TMS-456", "https://tms.example.org/TMS-456");
// ...
}
}
Jerarquía basada en el comportamiento
@Epic(String value="")
@Epics(Epic[] value)
@Feature(String value="")
@Features(Feature[] value)
@Story(String value="")
@Stories(Story[] value)
Allure.epic(String value)
Allure.feature(String value)
Allure.story(String value)
Asigna nombres de epics, características o historias de usuario para una prueba, como parte de la jerarquía basada en comportamiento de Allure.
import io.qameta.allure.Epic;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
@Epic("Web interface")
@Feature("Essential features")
@Story("Authentication")
void testAuthentication() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.epic("Web interface");
Allure.feature("Essential features");
Allure.story("Authentication");
// ...
}
}
Jerarquía basada en la suite
Asigna el nombre de la suite, como parte de la jerarquía basada en suites de Allure.
Para asignar los nombres de la suite principal o sub-suite, usa label()
con los nombres de las etiquetas correspondientes.
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.label("parentSuite" "Tests for web interface");
Allure.suite("Tests for essential features");
Allure.label("subSuite", "Tests for authentication");
// ...
}
}
Pasos de prueba
@Step(String value="")
Allure.step(String name)
Allure.step(String name, Status status)
Allure.step(String name, ThrowableRunnableVoid runnable)
Allure.step(String name, ThrowableRunnable<T> runnable)
Allure.step(ThrowableContextRunnableVoid<StepContext> runnable)
Allure.step(String name, ThrowableContextRunnableVoid<StepContext> runnable)
Allure.step(String name, ThrowableContextRunnable<T, StepContext> runnable)
Allure.step(ThrowableContextRunnable<T, StepContext> runnable)
Define un paso de prueba con el nombre
dado.
Hay tres formas de definir un paso.
- “Un paso anotado”: define un método que contenga un paso de prueba y decóralo con
@Step()
. - “Un paso lambda”: escribe un paso de prueba en una función lambda y pásalo a
Allure.step()
. - “Un paso no operativo”: simplemente pasa un
nombre
y unestado
opcional aAllure.step()
para agregar inmediatamente una entrada correspondiente a los resultados como un sub-paso del paso actual.
Cuando implementes una función para un paso lambda, puede aceptar ningún argumento o un único argumento de la clase StepContext
. Este objeto proporciona los siguientes métodos:
name()
— sobrescribe el nombre del paso durante su ejecución.parameter()
— indica parámetros arbitrarios usados para el paso. Las firmas disponibles de este método son las mismas que para la implementación a nivel de prueba, consulta Pruebas parametrizadas.
import io.qameta.allure.Step;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
step1();
step2();
}
@Step("Step 1")
void step1() {
subStep1();
subStep2();
}
@Step("Sub-step 1")
void subStep1() {
// ...
}
@Step("Sub-step 2")
void subStep2() {
// ...
}
@Step("Step 2")
void step2() {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthentication() {
Allure.step("Step 1", step -> {
// ...
Allure.step("Sub-step 1");
// ...
Allure.step("Sub-step 2");
});
Allure.step("Step 2", step -> {
// ...
});
}
}
Pruebas parametrizadas
@Param(String value="", String name="", Parameter.Mode mode=DEFAULT, boolean excluded=false)
Allure.parameter(String name, T value)
Allure.parameter(String name, T value, Boolean excluded)
Allure.parameter(String name, T value, Parameter.Mode mode)
Allure.parameter(String name, T value, Boolean excluded, Parameter.Mode mode)
Especifica un name
y value
de un parámetro que fue usado durante esta prueba. Esto puede ser usado para agregar los parámetros incluso a aquellas funciones que no usan el decorador @ParameterizedTest()
. Consulta Pruebas parametrizadas para más detalles.
WARNING
Allure JUnit 5 identifica las pruebas basándose únicamente en sus nombres y parámetros estáticos, como los definidos a través de @ValueSource
. Si tienes múltiples pruebas que solo difieren en parámetros dinámicos (es decir, las llamadas Allure.parameter()
), serán tratadas como una sola prueba para los fines de Historial y reintentos.
Si el argumento excluded
está configurado como verdadero, Allure no usará el parámetro al comparar el resultado actual de la prueba con el anterior en el historial. Este argumento solo es utilizado por Allure TestOps.
El argumento mode
afecta cómo se mostrará el parámetro en el informe. Las opciones disponibles están definidas en la enumeración Parameter.Mode
:
Parameter.Mode.DEFAULT
(igual que no especificar ningún modo) — el parámetro y su valor se mostrarán en una tabla junto con otros parámetros.Parameter.Mode.MASKED
— el parámetro se mostrará en la tabla, pero su valor estará oculto. Usa este modo para contraseñas, tokens y otros parámetros sensibles.Parameter.Mode.HIDDEN
— el parámetro y su valor no se mostrarán en el informe de la prueba. Sin embargo, ten en cuenta que aún es posible extraer el valor del directorioallure_results
si lo publicas.
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
class TestMyWebsite {
@ParameterizedTest(name = "{displayName} ({argumentsWithNames})")
@ValueSource(strings = {"johndoe", "[email protected]"})
void testAuthentication(String login) {
// ...
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
class TestMyWebsite {
@Test
void testAuthenticationWithUsername() {
Allure.parameter("login", "johndoe");
// ...
}
@Test
void testAuthenticationWithEmail() {
Allure.parameter("login", "[email protected]");
// ...
}
}
Ten en cuenta que, por defecto, el entorno de ejecución de Java no tiene acceso a los nombres de los argumentos de los métodos. Esto significa que la API de Anotaciones solo puede mostrar pseudo-nombres como “arg0”, “arg1”, etc. Para permitir que se muestren los nombres originales en el informe, agrega -parameters
en los compilerArgs
de tu proyecto. Por ejemplo (en el build.gradle.kts
del proyecto):
tasks.withType(JavaCompile::class) {
options.compilerArgs.add("-parameters")
}
Archivos adjuntos
@Attachment(String value="", String type="", String fileExtension="")
Allure.addAttachment(String name, String content)
Allure.addAttachment(String name, String type, String content)
Allure.addAttachment(String name, String type, String content, String fileExtension)
Allure.addAttachment(String name, InputStream content)
Allure.addAttachment(String name, String type, InputStream content, String fileExtension)
Allure.attachment(String name, String content)
Allure.attachment(String name, InputStream content)
Agrega content
como un archivo adjunto al resultado de la prueba bajo el nombre
dado (el valor predeterminado es una cadena pseudo-aleatoria única).
TIP
Puedes usar datos producidos por cualquier función, no necesariamente leídos desde un archivo real.
Para crear un archivo adjunto utilizando la API de Anotaciones, define un método que retorne algunos datos y anótalo con @Attachment
. Llama al método en cualquier punto durante tu prueba.
Para crear un archivo adjunto utilizando la API en tiempo de ejecución, simplemente llama a addAttachment()
o attachment()
en cualquier momento durante tu prueba. Pasa los datos como argumento content
.
Los datos serán procesados de la siguiente manera:
- Si el tipo de dato es
byte[]
, Allure lo usará sin modificación. - Si el tipo de dato es
String
, Allure lo convertirá abyte[]
. - Si los datos son de cualquier otro tipo, Allure llamará al método
toString()
y luego convertirá la cadena abyte[]
.
Para asegurarte de que el navegador web del lector mostrará los archivos adjuntos correctamente, se recomienda especificar el tipo de cada archivo adjunto. Para hacerlo, pasa el tipo de medio del contenido como type
y, opcionalmente, una extensión de archivo como fileExtension
. El tipo de medio afecta cómo se mostrará el dato en el informe de la prueba, mientras que la extensión de archivo se agrega al nombre del archivo cuando el usuario quiere guardar el archivo.
import io.qameta.allure.Attachment;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
class TestMyWebsite {
@Test
void testAuthentication() throws IOException {
// ...
attachDataTXT();
attachScreenshotPNG();
}
@Attachment(value = "data", type = "text/plain", fileExtension = ".txt")
public String attachDataTXT() {
return "This is the file content.";
}
@Attachment(value = "screenshot", type = "image/png", fileExtension = ".png")
public byte[] attachScreenshotPNG() throws IOException {
return Files.readAllBytes(Paths.get("/path/to/image.png"));
}
}
import io.qameta.allure.Allure;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
class TestMyWebsite {
@Test
void testAuthentication() throws IOException {
// ...
Allure.attachment("data.txt", "This is the file content.");
try (InputStream is = Files.newInputStream(Paths.get("/path/img.png"))) {
Allure.attachment("image.png", is);
}
}
}
INFO
Además, Allure proporciona una manera de generar hilos que agregarán archivos adjuntos a los resultados de la prueba de manera asíncrona sin bloquear el corredor de pruebas. Aunque no se recomienda para la mayoría de los casos, este enfoque puede mejorar las pruebas que, de otro modo, tendrían que esperar el procesamiento de archivos muy grandes, como videos de más de 1 GB. Consulta el código fuente de Allure.addByteAttachmentAsync()
y Allure.addStreamAttachmentAsync()
para obtener más información.
Historial de resultados
Inestable
@Flaky
Indica que se sabe que la prueba es inestable y puede no tener éxito cada vez. Consulta Pruebas inestables.