Introducción a Allure Framework
Allure Framework es una herramienta de reportes de pruebas de código abierto que transforma los resultados de ejecución de tests en reportes HTML interactivos y visualmente atractivos. A diferencia de los reportes estándar que simplemente muestran el estado aprobado/fallido, Allure proporciona información detallada sobre la ejecución de pruebas, tendencias históricas, categorización y adjuntos personalizados que hacen que la depuración sea más rápida y los reportes más profesionales.
¿Por Qué Elegir Allure?
Los reportes de pruebas tradicionales a menudo carecen de la profundidad necesaria para una depuración efectiva y comunicación con stakeholders. Allure aborda estas limitaciones ofreciendo:
- Visualizaciones ricas con gráficos, diagramas y líneas de tiempo
- Historial detallado de ejecución para rastrear tendencias a lo largo del tiempo
- Adjuntos personalizados incluyendo capturas de pantalla, logs y videos
- Categorización y etiquetado para mejor organización de pruebas
- Integración con frameworks de testing populares
Frameworks de Testing Soportados
Allure se integra perfectamente con los principales frameworks de testing en diferentes lenguajes de programación:
Framework | Lenguaje | Método de Integración |
---|---|---|
Pytest | Python | Adaptador allure-pytest |
JUnit 4/5 | Java | Adaptador allure-junit4/5 |
TestNG | Java | Adaptador allure-testng |
Cucumber | Java/Ruby | Adaptador allure-cucumber |
Jest | JavaScript | Adaptador jest-allure |
Mocha | JavaScript | Adaptador allure-mocha |
NUnit | C# | Adaptador allure-nunit |
PHPUnit | PHP | Adaptador allure-phpunit |
Comenzando con Allure
Instalación y Configuración
Para Python con Pytest:
pip install allure-pytest
Para Java con Maven (JUnit 5):
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
(como se discute en [REST Assured: Java-Based API Testing Framework for Modern Applications](/blog/rest-assured-api-testing)) <version>2.24.0</version>
<scope>test</scope>
</dependency>
Para Java con Gradle (TestNG):
dependencies {
testImplementation 'io.qameta.allure:allure-testng (como se discute en [TestNG vs JUnit 5: Complete Comparison for Java Testers](/blog/testng-vs-junit5)):2.24.0'
}
Herramienta de Línea de Comandos de Allure
Para generar y ver reportes, instala la herramienta de línea de comandos de Allure:
# macOS
brew install allure
# Windows (usando Scoop)
scoop install allure
# Linux
sudo apt-add-repository ppa:qameta/allure
sudo apt-get update
sudo apt-get install allure
Integración Profunda con Pytest
Configuración Básica
Crea un archivo pytest.ini
en la raíz de tu proyecto:
[pytest]
addopts = --alluredir=./allure-results
Escribiendo Tests con Decoradores de Allure
import allure
import pytest
@allure.epic("Plataforma E-Commerce")
@allure.feature("Carrito de Compras")
@allure.story("Agregar Artículos al Carrito")
@allure.severity(allure.severity_level.CRITICAL)
def test_add_item_to_cart():
with allure.step("Abrir página de producto"):
product_page = open_product_page("laptop-123")
with allure.step("Hacer clic en botón 'Agregar al Carrito'"):
product_page.click_add_to_cart()
with allure.step("Verificar que el artículo aparece en el carrito"):
cart = open_cart()
assert cart.item_count() == 1
assert "laptop-123" in cart.get_items()
@allure.title("Login con credenciales válidas")
@allure.description("""
Este test verifica que los usuarios pueden iniciar sesión
exitosamente con una combinación válida de usuario y contraseña.
""")
def test_valid_login():
allure.attach("admin", name="username", attachment_type=allure.attachment_type.TEXT)
login_page = LoginPage()
login_page.login("admin", "password123")
assert login_page.is_logged_in()
Adjuntos Personalizados
import allure
from selenium import webdriver
def test_screenshot_on_failure():
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
# Lógica del test aquí
assert False # Simular fallo
except AssertionError:
allure.attach(
driver.get_screenshot_as_png(),
name="failure_screenshot",
attachment_type=allure.attachment_type.PNG
)
raise
finally:
driver.quit()
def test_attach_json_response():
response = {"status": "success", "data": [1, 2, 3]}
allure.attach(
json.dumps(response, indent=2),
name="api_response",
attachment_type=allure.attachment_type.JSON
)
Integración con JUnit 5
Configuración Maven
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>io.qameta.allure.junit5.AllureJunit5</value>
</property>
</properties>
</configuration>
</plugin>
</plugins>
</build>
Ejemplo de Test Anotado
import io.qameta.allure.*;
import org.junit.jupiter.api.Test;
@Epic("Gestión de Usuarios")
@Feature("Registro de Usuario")
public class UserRegistrationTest {
@Test
@Story("Registrar nuevo usuario con datos válidos")
@Severity(SeverityLevel.BLOCKER)
@Description("Verificar que nuevos usuarios pueden registrarse con credenciales válidas")
public void testUserRegistration() {
step("Navegar a página de registro", () -> {
// Lógica de navegación
});
step("Llenar formulario de registro", () -> {
// Lógica de llenado de formulario
});
step("Enviar formulario y verificar éxito", () -> {
// Envío y verificación
});
}
@Step("Abrir aplicación en {url}")
public void openApp(String url) {
// Implementación
}
@Attachment(value = "Request body", type = "application/json")
public String attachJson(String json) {
return json;
}
}
Integración con TestNG
Configuración XML de TestNG
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Allure TestNG Suite">
<listeners>
<listener class-name="io.qameta.allure.testng.AllureTestNg"/>
</listeners>
<test name="Regression Tests">
<classes>
<class name="com.example.tests.LoginTest"/>
<class name="com.example.tests.CheckoutTest"/>
</classes>
</test>
</suite>
Ejemplo de Test con TestNG
import io.qameta.allure.*;
import org.testng.annotations.Test;
public class CheckoutTest {
@Test
@Epic("E-Commerce")
@Feature("Proceso de Checkout")
@Story("Completar compra")
@Severity(SeverityLevel.CRITICAL)
@Description("Verificar flujo completo de checkout desde carrito hasta confirmación de orden")
public void testCompletePurchase() {
addItemToCart("product-123");
proceedToCheckout();
fillShippingDetails();
selectPaymentMethod();
confirmOrder();
verifyOrderConfirmation();
}
@Step("Agregar artículo {productId} al carrito")
private void addItemToCart(String productId) {
// Implementación
}
}
Características Avanzadas
Tendencias Históricas
Allure mantiene el historial de ejecución de pruebas para mostrar tendencias a lo largo del tiempo. Configura el historial copiando resultados anteriores:
# Generar reporte actual
allure generate allure-results --clean -o allure-report
# Copiar historial para tendencias
cp -r allure-report/history allure-results/history
# Regenerar con historial
allure generate allure-results --clean -o allure-report
Configuración de Categorías
Crea categories.json
en el directorio allure-results
:
[
{
"name": "Defectos de Producto",
"matchedStatuses": ["failed"],
"messageRegex": ".*AssertionError.*"
},
{
"name": "Problemas de Test",
"matchedStatuses": ["broken"],
"messageRegex": ".*NullPointerException.*"
},
{
"name": "Tests Inestables",
"matchedStatuses": ["passed", "failed"],
"messageRegex": ".*timeout.*"
}
]
Información de Ambiente
Crea environment.properties
:
Browser=Chrome
Browser.Version=119.0
Stand=Production
OS=macOS 14.0
Java.Version=17.0.8
Integración con CI/CD
Pipeline de Jenkins
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'mvn clean test'
}
}
stage('Generate Allure Report') {
steps {
allure([
includeProperties: false,
jdk: '',
properties: [],
reportBuildPolicy: 'ALWAYS',
results: [[path: 'target/allure-results']]
])
}
}
}
}
GitHub Actions
name: Tests con Allure
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configurar Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Instalar dependencias
run: |
pip install -r requirements.txt
pip install allure-pytest
- name: Ejecutar tests
run: pytest --alluredir=./allure-results
- name: Obtener historial de Allure
uses: actions/checkout@v3
if: always()
continue-on-error: true
with:
ref: gh-pages
path: gh-pages
- name: Reporte Allure
uses: simple-elf/allure-report-action@master
if: always()
with:
allure_results: allure-results
allure_history: allure-history
keep_reports: 20
- name: Desplegar a GitHub Pages
if: always()
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages
publish_dir: allure-history
Mejores Prácticas
1. Descripciones de Pasos Significativas
# Mal
with allure.step("Paso 1"):
do_something()
# Bien
with allure.step("Login con usuario 'testuser' y verificar carga del dashboard"):
login("testuser", "password")
assert_dashboard_visible()
2. Adjuntar Capturas Solo en Fallos
import pytest
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
if rep.when == 'call' and rep.failed:
driver = item.funcargs.get('driver')
if driver:
allure.attach(
driver.get_screenshot_as_png(),
name='screenshot',
attachment_type=allure.attachment_type.PNG
)
3. Organizar con Epics, Features y Stories
@allure.epic("Portal de Clientes")
@allure.feature("Autenticación")
@allure.story("Reseteo de Contraseña")
def test_password_reset():
# Implementación del test
4. Usar Parámetros para Tests Data-Driven
@pytest.mark.parametrize("username,password", [
("user1", "pass1"),
("user2", "pass2"),
])
def test_login(username, password):
allure.dynamic.title(f"Test de login para {username}")
allure.dynamic.parameter("username", username)
# Lógica del test
Conclusión
Allure Framework eleva los reportes de pruebas de simples logs de aprobado/fallido a documentación completa e interactiva. Su soporte para múltiples frameworks, capacidades de visualización ricas e integración con CI/CD lo convierten en una herramienta esencial para equipos de QA modernos. Al implementar las características de Allure—desde anotaciones básicas hasta tendencias históricas avanzadas—los equipos obtienen conocimientos más profundos sobre la calidad de las pruebas, haciendo la depuración más rápida y la comunicación con stakeholders más efectiva.
Comienza con la integración básica, agrega gradualmente adjuntos personalizados y categorización, luego aprovecha los datos históricos y la integración CI/CD para obtener el máximo valor.