Pruebas de regresión
Las pruebas de regresión garantizan que los cambios nuevos, las correcciones de errores o los refactorizaciones no rompan la funcionalidad existente. Son un componente indispensable en cualquier estrategia de control de calidad, especialmente en equipos ágiles con ciclos de lanzamiento cortos. Sin pruebas de regresión, crece el miedo a los cambios y el código se vuelve frágil.
En resumen
- Las pruebas de regresión verifican que la funcionalidad anterior sigue funcionando.
- Se ejecutan después de cada cambio relevante.
- La automatización es esencial para escalar las pruebas de regresión.
- Las pruebas unitarias, de integración y E2E pueden servir como pruebas de regresión.
- Una buena estrategia prioriza los flujos críticos.
Descripción técnica concisa
Las pruebas de regresión son tests que verifican repetidamente características ya funcionales después de que algo ha cambiado en el software. El objetivo es detectar errores de regresión, es decir, fallos que aparecen en áreas previamente correctas como consecuencia de los nuevos cambios. Pueden ejecutarse manual o automáticamente, aunque la automatización es mucho más eficiente cuando hay cambios frecuentes.
Las pruebas de regresión no son un tipo de test en sí mismo, sino una estrategia de testing: decidir qué tests ya existentes deben ejecutarse nuevamente después de un cambio. La selección puede ser completa, basada en riesgo o guiada por análisis de impacto.
¿Cuándo se ejecutan las pruebas de regresión?
Las pruebas de regresión se utilizan cada vez que el código o el entorno del software cambian. Los desencadenantes más importantes son:
- Después de cambios de código o correcciones de errores: Cualquier cambio puede tener efectos secundarios. Las pruebas de regresión garantizan que la funcionalidad existente no se rompa accidentalmente.
- Después de refactorizaciones: Al reestructurar el código, el comportamiento debe mantenerse igual. Las pruebas de regresión ofrecen la seguridad de que no ha ocurrido ningún cambio de comportamiento.
- Después de actualizar dependencias: Las nuevas versiones de bibliotecas o frameworks pueden introducir cambios incompatibles. Las pruebas de regresión verifican que el sistema sigue funcionando correctamente.
- Después de fusionar en la rama principal: Antes de integrar código en main, se ejecutan pruebas de regresión para detectar conflictos y efectos secundarios temprano.
- Antes de un lanzamiento: Justo antes de la entrega, se ejecuta una suite completa de regresión para confirmar la calidad general.
- En compilaciones nocturnas regulares: Las ejecuciones automatizadas durante la noche capturan regresiones que no fueron detectadas durante el día.
Tipos de pruebas de regresión
Pruebas unitarias de regresión
Las pruebas unitarias de regresión verifican funciones o clases individuales después de cambios. Son rápidas y se ejecutan frecuentemente, idealmente en cada commit. Son la primera línea de defensa contra regresiones porque se ejecutan de forma aislada en milisegundos. Un ejemplo típico: una función de cálculo de descuentos se modifica. Las pruebas unitarias verifican todas las reglas de descuento anteriores y garantizan que los resultados siguen siendo idénticos.
Pruebas de integración de regresión
Las pruebas de integración de regresión verifican interfaces e interacciones entre módulos que podrían verse afectados por un cambio. Son más lentas que las pruebas unitarias, pero importantes para encontrar efectos secundarios en los límites de los módulos. Un ejemplo: después de un cambio en el cálculo de precios, se prueba si el carrito, la pasarela de pago y la generación de facturas siguen funcionando correctamente.
Pruebas E2E de regresión
Las pruebas E2E de regresión validan flujos críticos del usuario final, por ejemplo el proceso de compra en una tienda. Son las pruebas más lentas y costosas, pero cubren toda la cadena. Deben utilizarse de forma dirigida para procesos empresariales críticos, no para cada pequeño cambio.
Estrategias de pruebas de regresión
Regresión completa
Se ejecutan todas las pruebas existentes. Es la opción más segura, pero con suites de pruebas grandes consume mucho tiempo. Típicamente se usa solo antes de lanzamientos o en compilaciones nocturnas.
Regresión basada en riesgo
Se ejecutan solo las pruebas que cubren funcionalidad crítica o frecuentemente utilizada. Esta estrategia requiere priorizar las pruebas según criticidad y frecuencia de uso.
Análisis de impacto de pruebas
El análisis de impacto identifica qué áreas del código se ven afectadas por un cambio y ejecuta solo las pruebas que cubren esas áreas. Esto requiere herramientas que puedan analizar las dependencias en el código.
Ejemplo práctico
El siguiente ejemplo muestra cómo se emplean las pruebas de regresión en la práctica. Se eligió porque integra los tres niveles de testing y demuestra cómo un cambio específico lleva a una estrategia de testing sistemática.
Un desarrollador cambia la lógica de descuentos en checkout.
Pruebas de regresión:
- Tests unitarios para todas las reglas de descuento
- Pruebas de integración para carrito y cálculo de precio
- Test E2E para el flujo completo de checkout
- Testing exploratorio de funciones de descuento anteriores
¿Por qué estas pruebas?
- Tests unitarios: La lógica de descuentos es una función aislable. Los tests unitarios verifican cada regla de descuento individualmente y garantizan que el cálculo sigue siendo correcto para todos los casos previos.
- Pruebas de integración: El carrito y el cálculo de precio dependen directamente de la lógica de descuentos. Las pruebas de integración verifican que el cálculo de precio total sigue siendo correcto con las nuevas reglas de descuento.
- Test E2E: El flujo completo de checkout es el proceso empresarial más crítico. Un test E2E garantiza que el usuario puede completar la compra sin errores.
- Testing exploratorio: Las pruebas automatizadas cubren casos conocidos. El testing exploratorio encuentra efectos secundarios inesperados que las pruebas automatizadas no incluyen.
Ventajas y desventajas
| Ventajas | Desventajas |
|---|---|
| Protección contra errores de regresión | Suite de pruebas en crecimiento con muchas características |
| Confianza en refactorizaciones y cambios de código | Tiempos de ejecución largos sin buena estrategia |
| Lanzamientos más seguros y frecuentes | Esfuerzo de mantenimiento de pruebas |
| Detección temprana de efectos secundarios | Las pruebas de regresión manuales son costosas y lentas |
| Documentación viva del comportamiento esperado | Los falsos positivos pueden erosionar la confianza |
| Evaluación objetiva de calidad antes del lanzamiento | Esfuerzo inicial para la automatización |
Mejores prácticas
- Automatiza: Las pruebas de regresión manuales no escalan con cambios frecuentes.
- Prioriza: No todas las pruebas son igual de importantes. Los flujos críticos primero.
- Mantén la mantenibilidad: Las pruebas deben ser fáciles de ajustar cuando el código cambia.
- Mantenlas rápidas: Suites de pruebas lentas ralentizan el desarrollo. La paralelización y la selección dirigida ayudan.
- Integra en CI/CD: Las pruebas de regresión deben ejecutarse automáticamente en cada commit o merge.
- Evita falsos positivos: Las pruebas inestables destruyen la confianza en la suite.
- Usa análisis de impacto: Ejecuta solo las pruebas afectadas para ahorrar tiempo.
Ejemplo práctico completo: Proyecto FastAPI + NiceGui con Docker y CI/CD
Contexto del proyecto
El proyecto está compuesto por:
- FastAPI como backend — proporciona endpoints API para herramientas de conversión de texto (por ejemplo, Markdown→HTML, JSON→YAML, codificación/decodificación Base64, estadísticas de texto)
- NiceGui como frontend — interfaz web que invoca los endpoints de la API y muestra los resultados
- Docker — la herramienta se ejecuta localmente para desarrollo y en el servidor mediante contenedores Docker
- Módulos adicionales — como
pydanticpara validación,httpxpara solicitudes HTTP asincrónicas,python-slugifypara generación de slugs de URL
El problema con Vibecoding: La generación de código impulsada por IA suele cambiar de forma involuntaria otros archivos, elimina bibliotecas o modifica importaciones. Una función que funcionaba ayer de repente está rota, sin que el desarrollador lo advierta porque el cambio ocurrió en un sitio completamente distinto.
Estructura del proyecto
my-text-tools/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI-App, registriert Router
│ ├── routers/
│ │ ├── __init__.py
│ │ ├── markdown.py # /api/markdown → HTML
│ │ ├── json_yaml.py # /api/json-to-yaml, /api/yaml-to-json
│ │ ├── base64.py # /api/base64/encode, /api/base64/decode
│ │ └── stats.py # /api/stats (Wörter, Zeichen, Zeilen)
│ ├── models/
│ │ ├── __init__.py
│ │ └── schemas.py # Pydantic-Modelle für Request/Response
│ ├── services/
│ │ ├── __init__.py
│ │ ├── converter.py # Kernlogik: Konvertierungsfunktionen
│ │ └── slugify.py # Slug-Erzeugung
│ └── ui/
│ ├── __init__.py
│ └── nicegui_app.py # NiceGui-Frontend, ruft API auf
├── tests/
│ ├── __init__.py
│ ├── conftest.py # pytest-Fixtures (Test-Client, Mocks)
│ ├── unit/
│ │ ├── test_converter.py
│ │ ├── test_slugify.py
│ │ └── test_models.py
│ ├── integration/
│ │ ├── test_markdown_api.py
│ │ ├── test_json_yaml_api.py
│ │ ├── test_base64_api.py
│ │ └── test_stats_api.py
│ └── e2e/
│ └── test_ui_flows.py # NiceGui-UI-Tests via Playwright
├── Dockerfile
├── docker-compose.yml
├── docker-compose.test.yml # Test-Environment mit isolierter DB
├── requirements.txt
├── requirements-dev.txt # pytest, pytest-asyncio, httpx, playwright
├── .github/
│ └── workflows/
│ ├── ci.yml # Lint + Unit + Integration bei jedem Push
│ └── nightly.yml # Vollständige Regressionssuite nachts
├── Makefile # make test, make test-unit, make test-e2e
└── pytest.ini
Paso 1: Tests de regresión unitarios con pytest
Los tests unitarios verifican la lógica central de forma aislada, sin base de datos, sin red y sin interfaz de usuario.
# tests/unit/test_converter.py
import pytest
from app.services.converter import (
markdown_to_html,
json_to_yaml,
yaml_to_json,
base64_encode,
base64_decode,
text_statistics,
)
class TestMarkdownToHtml:
"""Regressionstests für Markdown-Konvertierung."""
def test_simple_heading(self):
assert markdown_to_html("# Titel") == "<h1>Titel</h1>"
def test_bold_text(self):
assert markdown_to_html("**fett**") == "<strong>fett</strong>"
def test_code_block(self):
md = "```python\nprint('hello')\n```"
result = markdown_to_html(md)
assert "<code>" in result
assert "print('hello')" in result
def test_empty_input(self):
assert markdown_to_html("") == ""
def test_nested_lists(self):
md = "- Item 1\n - Subitem 1.1"
result = markdown_to_html(md)
assert "<ul>" in result
assert "<li>Item 1" in result
# Regression: Vibecoding entfernt Bibliothek → ImportError
def test_module_imports_successfully(self):
"""Stellt sicher, dass der Converter importierbar bleibt.
Wenn Vibecoding z.B. 'markdown' aus requirements.txt entfernt,
schlägt dieser Test fehl."""
from app.services import converter
assert hasattr(converter, 'markdown_to_html')
class TestJsonYamlConversion:
"""Regressionstests für JSON↔YAML-Konvertierung."""
def test_json_to_yaml_basic(self):
json_input = '{"name": "test", "value": 42}'
result = json_to_yaml(json_input)
assert "name: test" in result
assert "value: 42" in result
def test_roundtrip_json_yaml_json(self):
"""JSON → YAML → JSON muss identisch sein."""
import json
original = {"name": "test", "list": [1, 2, 3]}
json_str = json.dumps(original)
yaml_str = json_to_yaml(json_str)
back = yaml_to_json(yaml_str)
assert json.loads(back) == original
def test_nested_structures(self):
json_input = '{"outer": {"inner": {"deep": true}}}'
result = json_to_yaml(json_input)
assert "inner:" in result
assert "deep: true" in result
class TestBase64:
"""Regressionstests für Base64-De-/Encoding."""
def test_encode_decode_roundtrip(self):
original = "Hello, World!"
encoded = base64_encode(original)
decoded = base64_decode(encoded)
assert decoded == original
def test_encode_empty_string(self):
assert base64_encode("") == ""
def test_decode_invalid_input_raises(self):
with pytest.raises(Exception):
base64_decode("!!!invalid_base64!!!")
class TestTextStatistics:
"""Regressionstests für Text-Statistiken."""
def test_word_count(self):
stats = text_statistics("hello world foo")
assert stats["words"] == 3
def test_empty_text(self):
stats = text_statistics("")
assert stats["words"] == 0
assert stats["characters"] == 0
assert stats["lines"] == 0
def test_multiline(self):
stats = text_statistics("line1\nline2\nline3")
assert stats["lines"] == 3
# tests/unit/test_slugify.py
from app.services.slugify import slugify
class TestSlugify:
"""Regression: Wenn python-slugify aus requirements entfernt wird,
schlägt dieser Test fehl — schützt vor unbemerktem Bibliotheksverlust."""
def test_basic_slug(self):
assert slugify("Hello World") == "hello-world"
def test_german_umlauts(self):
assert slugify("Übergröße") == "ubergrose"
def test_special_characters(self):
assert slugify("Python 3.12!@#") == "python-312"
def test_empty_string(self):
assert slugify("") == ""
Paso 2: Tests de regresión de integración con pytest + httpx
Los tests de integración verifican los endpoints de la API a través del TestClient de FastAPI.
# tests/conftest.py
import pytest
from fastapi.testclient import TestClient
from app.main import app
@pytest.fixture
def client():
"""FastAPI Test-Client für Integrationstests."""
return TestClient(app)
@pytest.fixture
def sample_markdown():
return "# Test\n\n**Bold** text with `code`."
# tests/integration/test_markdown_api.py
class TestMarkdownAPI:
"""Regressionstests für den /api/markdown Endpunkt."""
def test_markdown_to_html_success(self, client, sample_markdown):
response = client.post("/api/markdown", json={"text": sample_markdown})
assert response.status_code == 200
data = response.json()
assert "<h1>Test</h1>" in data["html"]
assert "<strong>Bold</strong>" in data["html"]
def test_markdown_empty_input(self, client):
response = client.post("/api/markdown", json={"text": ""})
assert response.status_code == 200
assert response.json()["html"] == ""
def test_markdown_missing_field(self, client):
"""Regression: Pydantic-Validierung muss aktiv bleiben.
Wenn Vibecoding das Modell ändert, schlägt dieser Test fehl."""
response = client.post("/api/markdown", json={})
assert response.status_code == 422 # Validation Error
def test_markdown_invalid_json(self, client):
response = client.post("/api/markdown", data="not json")
assert response.status_code == 422
# tests/integration/test_stats_api.py
class TestStatsAPI:
"""Regressionstests für /api/stats."""
def test_stats_basic(self, client):
response = client.post("/api/stats", json={"text": "hello world"})
assert response.status_code == 200
data = response.json()
assert data["words"] == 2
assert data["characters"] == 11
def test_stats_empty(self, client):
response = client.post("/api/stats", json={"text": ""})
assert response.status_code == 200
assert response.json()["words"] == 0
# Regression: Stellt sicher, dass der Endpunkt überhaupt existiert.
# Wenn Vibecoding einen Router entfernt, schlägt dies fehl.
def test_stats_endpoint_exists(self, client):
response = client.post("/api/stats", json={"text": "test"})
assert response.status_code != 404
Paso 3: Tests de regresión E2E con Playwright
Los tests E2E validan la interfaz de NiceGui a través de un navegador real.
# tests/e2e/test_ui_flows.py
"""Tests de regresión E2E para la interfaz de NiceGui.
Requiere que la aplicación esté ejecutándose (docker-compose up -d)."""
import pytest
from playwright.sync_api import Page, expect
BASE_URL = "http://localhost:8080"
class TestMarkdownConverterUI:
"""Valida que la conversión de Markdown funciona a través de la UI."""
def test_markdown_input_and_output(self, page: Page):
page.goto(BASE_URL)
page.fill("[data-testid='markdown-input']", "# Hola Mundo")
page.click("[data-testid='convert-button']")
output = page.locator("[data-testid='markdown-output']")
expect(output).to_contain_text("Hola Mundo")
expect(output).to_contain_text("<h1>")
def test_clear_button(self, page: Page):
page.goto(BASE_URL)
page.fill("[data-testid='markdown-input']", "# Test")
page.click("[data-testid='clear-button']")
assert page.locator("[data-testid='markdown-input']").input_value() == ""
class TestNavigationRegression:
"""Asegura que todos los tabs de la UI permanecen accesibles.
Si Vibecoding elimina un tab, esto fallará."""
@pytest.mark.parametrize("tab_name", [
"Markdown", "JSON/YAML", "Base64", "Estadísticas"
])
def test_tab_accessible(self, page: Page, tab_name):
page.goto(BASE_URL)
page.click(f"text={tab_name}")
# Valida que el contenido del tab es visible
content = page.locator("[data-testid='tab-content']")
expect(content).to_be_visible()
Paso 4: Configuración de tests con Docker
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Inicia NiceGui + FastAPI
EXPOSE 8080
CMD ["python", "-m", "app.main"]
# docker-compose.test.yml
# Entorno de testing aislado — sin acceso a datos de producción
version: "3.9"
services:
app-test:
build:
context: .
dockerfile: Dockerfile
ports:
- "8081:8080" # Puerto diferente al de producción
environment:
- TESTING=true
- LOG_LEVEL=DEBUG
command: >
bash -c "pip install -r requirements-dev.txt &&
pytest tests/unit tests/integration -v --tb=short &&
pytest tests/e2e -v --tb=short"
Paso 5: Pipeline CI/CD con GitHub Actions
# .github/workflows/ci.yml
name: CI Regression Tests
on:
push:
branches: [main, dev]
pull_request:
branches: [main]
jobs:
unit-and-integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements.txt -r requirements-dev.txt
- run: pytest tests/unit tests/integration -v --tb=short --junitxml=results.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: results.xml
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements.txt -r requirements-dev.txt
- run: playwright install --with-deps chromium
- name: Start app in background
run: |
python -m app.main &
sleep 5
- run: pytest tests/e2e -v --tb=short
docker-build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: docker compose -f docker-compose.test.yml up --exit-code-from app-test
# .github/workflows/nightly.yml
name: Nightly Full Regression
on:
schedule:
- cron: "0 2 * * *" # Cada noche a las 02:00
jobs:
full-regression:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements.txt -r requirements-dev.txt
- run: playwright install --with-deps chromium
- name: Start app
run: python -m app.main & sleep 5
- name: Full regression suite
run: pytest -v --tb=long --junitxml=nightly-results.xml
- name: Notify on failure
if: failure()
run: |
echo "::error::Nightly regression failed — check logs"
Paso 6: Makefile para ejecución local
# Makefile
.PHONY: test test-unit test-integration test-e2e test-docker test-watch
test: test-unit test-integration
@echo "✅ Tests de Unit + Integration aprobados"
test-unit:
pytest tests/unit -v --tb=short
test-integration:
pytest tests/integration -v --tb=short
test-e2e:
pytest tests/e2e -v --tb=short
test-docker:
docker compose -f docker-compose.test.yml up --exit-code-from app-test
test-watch:
ptw -- -v --tb=short tests/
test-coverage:
pytest --cov=app --cov-report=html tests/unit tests/integration
@echo "📊 Coverage Report: htmlcov/index.html"
Paso 7: Documentación de los tests
Cada archivo de test debe estar documentado. Estructura recomendada:
docs/
├── testing.md # Estrategia de testing e instrucciones
├── test-cases.md # Listado de todos los casos de test con descripción
└── troubleshooting.md # Problemas conocidos y soluciones
docs/testing.md debe contener:
- Estrategia de testing — cuáles tests se ejecutan cuándo (Unit en commit, Integration en PR, E2E nightly)
- Ejecución —
make test,make test-unit,make test-docker - Integración CI/CD — qué workflows existen y cuándo se disparan
- Agregar nuevos tests — convenciones para nombres de archivos, fixtures, assertions
- Cobertura de tests —
make test-coveragey objetivo de cobertura (p. ej. ≥ 80%) - Troubleshooting — fallos comunes y soluciones
Paso 8: Recomendaciones específicas para Vibecoding
Con Vibecoding (generación de código asistida por IA) las regresiones frecuentemente ocurren por:
- Imports removidos — la IA elimina un
importen un archivo que otro archivo necesita - Firmas de función cambiadas — parámetros se renombran o se eliminan
- Funciones auxiliares eliminadas — la IA considera una función “no usada” y la elimina
- Modelos Pydantic alterados — campos se eliminan o renombran, la validación de API cambia
Medidas de protección:
-
Tests de Import Guard — cada archivo de test comienza con un test que importa todos los módulos relevantes:
def test_module_imports(): """Regresión: Asegura que todos los módulos permanezcan importables.""" import app.services.converter import app.services.slugify import app.routers.markdown import app.routers.stats -
Tests de contrato de API — validan que los endpoints respondan con los campos esperados:
def test_stats_response_schema(client): """Regresión: Si el modelo Pydantic cambia, esto fallará.""" response = client.post("/api/stats", json={"text": "test"}) data = response.json() assert "words" in data assert "characters" in data assert "lines" in data -
Check de dependencias — un test que parsea
requirements.txty valida que todos los paquetes importados estén listados:def test_all_imports_in_requirements(): """Regresión: Si Vibecoding elimina un import pero el código aún lo referencia, o viceversa.""" # Parsea requirements.txt with open("requirements.txt") as f: requirements = { line.split("==")[0].split(">=")[0].strip().lower() for line in f if line.strip() and not line.startswith("#") } # Valida paquetes críticos assert "fastapi" in requirements assert "nicegui" in requirements assert "pydantic" in requirements assert "httpx" in requirements assert "python-slugify" in requirements -
Pre-Commit Hook — ejecuta los tests de unit antes de cada commit:
# .git/hooks/pre-commit #!/bin/bash pytest tests/unit -v --tb=short || exit 1 -
Git Diff Review — después de cada sesión de Vibecoding revisa
git diff:git diff --stat # ¿Qué archivos fueron modificados? git diff requirements.txt # ¿Se removieron paquetes? git diff app/services/ # ¿Cambió la lógica central?
Resumen: Pirámide de pruebas para este proyecto
| Nivel | Herramienta | Cuándo | Duración | Cantidad |
|---|---|---|---|---|
| Unit | pytest | En cada commit | < 5 s | 30–50 |
| Integración | pytest + TestClient | En cada PR | < 30 s | 15–25 |
| E2E | Playwright | Nightly + antes de release | 2–5 min | 5–10 |
| Docker | docker-compose.test | En cada PR | 1–2 min | 1 Suite |
Regla: Si un cambio de código modifica una función, los tests unitarios e integración de esa área deben pasar en verde antes de hacer el commit.
Herramientas importantes
- JUnit / pytest / Jest: Frameworks para tests de regresión unitarios.
- Selenium / Cypress / Playwright: Herramientas para tests de regresión E2E.
- Postman / REST Assured: Para tests de regresión de API.
- TestNG / NUnit: Frameworks con funciones avanzadas de gestión de tests.
- Jenkins / GitHub Actions / GitLab CI: Pipelines de CI/CD para ejecutar automáticamente tests de regresión.
Puntos clave para el examen
- Test de regresión: Test que verifica que las funciones existentes sigan funcionando correctamente tras cambios en el código.
- Bug de regresión: Error causado por un cambio nuevo en un área que funcionaba previamente.
- Disparadores: Cambios de código, correcciones de bugs, refactoring, actualizaciones de dependencias, merges, releases.
- Niveles de test: Unit, integración y E2E pueden usarse como tests de regresión.
- Estrategias: Regresión completa, regresión basada en riesgo, análisis de impacto en tests.
- Automatización: Esencial para tests de regresión escalables y repetibles.
- Smoke test: Test mínimo que verifica si el sistema funciona en general.
- Sanity test: Test dirigido que valida un cambio pequeño.
- Nightly build: Ejecución automatizada de tests nocturna para detección temprana.
- Integración CI/CD: Los tests de regresión se ejecutan automáticamente en cada commit o merge.
- Mantenimiento: Los tests deben actualizarse cuando cambia el código.
- False positives: Los tests inestables pueden destruir la confianza en la suite.
Fuentes principales
- https://www.guru99.com/regression-testing.html
- https://www.atlassian.com/continuous-delivery/software-testing/regression-testing
- https://en.wikipedia.org/wiki/Regression_testing
Preguntas frecuentes
¿Qué es un test de regresión?
Un test de regresión verifica que las funciones existentes sigan funcionando correctamente después de cambios en el código. Evita que nuevas funcionalidades o correcciones de bugs rompan características ya existentes.
¿Cuándo se ejecutan los tests de regresión?
Después de cambios de código, correcciones de bugs, refactoring, actualizaciones de dependencias, merges a la rama principal, antes de releases y en builds nocturnos.
¿Qué es un bug de regresión?
Un bug de regresión es un error causado por un cambio nuevo en un área que funcionaba previamente. Es difícil de encontrar porque el cambio se realizó en otro lugar.
¿Por qué se automatizan los tests de regresión?
Porque son rápidos, repetibles y escalables. Los tests de regresión manuales son demasiado lentos cuando hay cambios frecuentes y propensos a errores.
¿En qué niveles se ejecutan los tests de regresión?
En todos los niveles: los tests unitarios verifican funciones aisladas, los tests de integración verifican interfaces y los tests E2E validan flujos completos de usuario.
¿Qué es una estrategia de test de regresión?
Una estrategia que define qué tests se ejecutan después de un cambio. Los enfoques posibles incluyen regresión completa, selección basada en riesgo o análisis de impacto en tests.
¿Debo repetir todos los tests siempre?
No. En suites de tests grandes, eso consume demasiado tiempo. En su lugar, debes priorizar según el riesgo o realizar un análisis de impacto en los tests.
¿Qué es un smoke test?
Un smoke test es un test mínimo que verifica si el sistema funciona en general y si las funciones más importantes están disponibles.
¿Qué es un sanity test?
Un sanity test es un test muy dirigido que valida un cambio pequeño. Es más rápido que una suite de regresión completa.
¿Cómo se seleccionan los tests de regresión?
Según la criticidad de la función, frecuencia de uso e impacto del cambio. Los caminos críticos siempre se prueban, los menos importantes solo cuando es necesario.
¿Cuál es una ventaja de los tests de regresión?
Proporcionan confianza en cambios y refactoring, permiten releases más frecuentes y reducen el riesgo de efectos secundarios en producción.
¿Cuál es una desventaja de los tests de regresión manuales?
Son caros, lentos y propensos a errores. Con cambios frecuentes, no son escalables y a menudo resultan en cobertura incompleta.
¿Con qué frecuencia deben ejecutarse los tests de regresión?
Los tests de regresión automatizados deben ejecutarse en cada commit o merge. Adicionalmente, los builds nocturnos pueden ejecutar una suite de regresión completa.
¿Qué es un análisis de impacto en tests?
El análisis de impacto en tests identifica qué áreas de código se ven afectadas por un cambio y ejecuta solo los tests que cubren esas áreas.
¿Pueden los tests de regresión prevenir que surjan bugs?
No previenen bugs directamente, pero detectan rápidamente errores secundarios causados por cambios antes de que lleguen a producción.
¿Qué es un falso positivo en tests de regresión?
Un falso positivo es un test que falla aunque el código sea correcto. Las causas comunes incluyen tests inestables, problemas de timing o datos de prueba incorrectos.
¿Cuál es la diferencia entre un smoke test y un sanity test?
Un smoke test verifica el sistema ampliamente pero superficialmente. Un sanity test verifica dirigidamente un cambio específico. Los smoke tests son más amplios, los sanity tests más profundos.
¿Qué herramientas son adecuadas para tests de regresión?
JUnit, pytest y Jest para tests unitarios. Selenium, Cypress y Playwright para tests E2E. Postman para tests de API. Jenkins y GitHub Actions para integración CI/CD.
¿Qué es un nightly build?
Un nightly build es un build y ejecución de tests automatizado que se realiza cada noche para detectar regresiones que no fueron notadas durante el día.
¿Cuál es la diferencia entre un test de regresión y un retest?
Un retest verifica si un bug específico se ha corregido después del fix. Un test de regresión verifica que otras funciones no se hayan roto por el fix.
Continúa con la ruta de aprendizaje de Software Testing
El siguiente artículo en la ruta de aprendizaje de Software Testing trata sobre pruebas de aceptación — cómo las pruebas de aceptación garantizan que se cumplan los requisitos.



