Flujo de trabajo de CI/Pruebas 🧪
La integración continua (CI) es esencial para mantener un código de alta calidad al detectar problemas de forma temprana. Esta guía cubre las pruebas de CI y las comprobaciones de calidad para los proyectos de Ultralytics.
Acciones de CI 🔄
Todas las PR deben pasar las comprobaciones automatizadas de CI antes de fusionarse. Nuestra canalización de CI incluye:
Pruebas de CI
Prueba primaria de CI que ejecuta pruebas unitarias, comprobaciones de linting y pruebas exhaustivas.
Implementación de Docker
Valida la implementación utilizando Docker, asegurando que Dockerfile y los scripts relacionados funcionen correctamente.
Enlaces rotos
Escanea la base de código en busca de enlaces rotos o no válidos en archivos markdown y HTML.
Análisis de CodeQL
Herramienta de análisis semántico de GitHub para encontrar posibles vulnerabilidades de seguridad y mantener la calidad del código.
Publicación en PyPI
Valida que el proyecto se pueda empaquetar y publicar en PyPI sin errores.
Pruebas de plataforma 🖥️
Pruebas ejecutadas en múltiples entornos:
- SO: Ubuntu, Windows, macOS
- Python: 3.8, 3.9, 3.10, 3.11, 3.12
Cobertura de código 📊
Utilizamos Codecov para medir y visualizar la cobertura del código, proporcionando información sobre qué tan bien las pruebas ejercitan la base de código.
Integración de la cobertura
La integración de Codecov proporciona:
- Información detallada de la cobertura
- Comparaciones de cobertura entre commits
- Superposiciones visuales en el código que muestran las líneas cubiertas
- Porcentaje de cobertura para el
ultralytics
paquete
Ver detalles completos de la cobertura en codecov.io/github/ultralytics/ultralytics.
Comprensión de la cobertura
La cobertura del código muestra qué porcentaje del código se ejecuta durante las pruebas. Una alta cobertura indica un código bien probado, pero no garantiza la ausencia de errores. La cobertura ayuda a identificar áreas no probadas que podrían ser propensas a errores.
Ejecución de pruebas localmente 🖥️
Instalar dependencias de desarrollo
Ejecutar todas las pruebas
Ejecutar pruebas específicas
# Single file
pytest tests/test_engine.py
# Single test function
pytest tests/test_engine.py::test_train
# Tests matching pattern
pytest -k "export"
# Slow tests only
pytest -m slow
Ejecutar con cobertura
Pruebas en paralelo
Pre-commit Hooks 🪝
Configure hooks de pre-commit para detectar problemas antes de subir:
Los hooks se ejecutan automáticamente:
- Ruff (linting y formateo)
- docformatter (formateo de cadenas de documentación)
- Eliminación de espacios en blanco finales
- Validación YAML
Ejecutar manualmente:
Escribir pruebas ✍️
Estructura de las pruebas
from pathlib import Path
from ultralytics import YOLO
def test_model_export():
"""Test ONNX model export."""
model = YOLO("yolo11n.pt")
model.export(format="onnx")
assert Path("yolo11n.onnx").exists()
Buenas prácticas
- Nombres descriptivos:
test_export_onnx_format()
notest_1()
- Aserción única: Pruebe una cosa por función
- Pruebas rápidas: Utiliza modelos/conjuntos de datos pequeños
- Fixtures: Utiliza fixtures de pytest para la configuración/desmontaje
- Marcadores:
@pytest.mark.slow
para pruebas de larga duración
Organización de las pruebas
tests/
├── test_engine.py # Training, validation, prediction
├── test_nn.py # Model architecture
├── test_data.py # Dataset handling
├── test_utils.py # Utility functions
└── test_exports.py # Export formats
Marcadores de prueba
import pytest
@pytest.mark.slow
def test_full_training():
"""Test full training run (slow)."""
model = YOLO("yolo11n.pt")
model.train(data="coco128.yaml", epochs=1)
Comprobaciones de calidad del código 🎯
Formateo con Ruff
# Check formatting
ruff check ultralytics/
# Auto-fix issues
ruff check --fix ultralytics/
# Format code
ruff format ultralytics/
Obtenga más información sobre los estándares de código en nuestro flujo de trabajo de desarrollo.
Verificación de tipos
Formato de cadenas de documentación
# Check docstrings
docformatter --check ultralytics/
# Auto-fix
docformatter --in-place ultralytics/
Solución de problemas de CI 🔧
Las pruebas pasan localmente, pero fallan en CI
Causas comunes:
- Problemas específicos de la plataforma: Prueba en el SO de destino
- Diferencias en la versión de python: Verifica la compatibilidad de la versión
- Dependencias faltantes: Verifica la configuración de CI
- Problemas de sincronización/concurrencia: Agrega reintentos o aumenta los tiempos de espera
Ejecuciones de CI lentas
Soluciones:
- Utiliza
@pytest.mark.slow
para pruebas costosas - Simula dependencias externas
- Reduce los tamaños de los conjuntos de datos de prueba
- Paraleliza con
pytest-xdist
Pruebas inestables
Correcciones:
- Agrega reintentos para pruebas dependientes de la red
- Aumenta los tiempos de espera para operaciones lentas
- Corrige las condiciones de carrera en el código asíncrono
- Utiliza semillas aleatorias deterministas
Evaluaciones comparativas de rendimiento 📈
CI rastrea métricas clave:
- Velocidad de inferencia (FPS)
- Uso de memoria
- Tamaño del modelo
- Tiempos de exportación
Las regresiones significativas impiden la fusión. Si las métricas cambian:
- Verificar que el cambio sea el esperado
- Documentar la razón en la PR
- Obtener la aprobación de los mantenedores
Estado de CI 📋
Comprobar el estado de CI para todos los repositorios de Ultralytics en docs.ultralytics.com/help/CI.
Insignias del repositorio principal
Omitir comprobaciones de CI ⚠️
Añadir [skip ci]
al mensaje de commit para omitir CI (usar con moderación):
Solo para:
- Cambios solo de documentación
- Actualizaciones de archivos que no son de código
- Correcciones urgentes de emergencia (con aprobación)
Recursos 📚
- Guía oficial de CI - Documentación completa de CI
- Flujo de trabajo de desarrollo - Proceso de PR y estándares de código
- Documentación de GitHub Actions - Configuración de CI
- Documentación de pytest - Framework de pruebas
- Codecov - Informes de cobertura