Ejercicio práctico: Crea un workflow que falle si los tests no pasan

Lectura
30 min~5 min lectura

Concepto clave

En el desarrollo de software moderno, la integración continua (CI) no es solo una práctica recomendada, es una necesidad. Imagina que eres un arquitecto que supervisa la construcción de un rascacielos. No esperarías a que el edificio esté completo para revisar si los cimientos son sólidos, ¿verdad? De la misma manera, en CI/CD, no debes esperar a desplegar tu aplicación para descubrir que los tests fallan.

Un workflow que falle si los tests no pasan actúa como tu sistema de alerta temprana. Cuando un desarrollador hace un commit o un pull request, este workflow se ejecuta automáticamente, ejecutando los tests de tu aplicación. Si algún test falla, el workflow marca la ejecución como fallida, bloqueando potencialmente la fusión del código o el despliegue. Esto garantiza que solo el código probado y funcional avance en el pipeline, manteniendo la estabilidad de tu base de código.

Cómo funciona en la práctica

Vamos a desglosar cómo implementar esto paso a paso en GitHub Actions. Primero, necesitas un repositorio con tests configurados. Supongamos que tienes una aplicación Node.js con tests escritos en Jest. El objetivo es crear un workflow que:

  1. Se active en eventos como push o pull request.
  2. Configure el entorno (en este caso, Node.js).
  3. Instale las dependencias.
  4. Ejecute los tests.
  5. Falle automáticamente si los tests no pasan.

GitHub Actions maneja el "fallo" a través de los estados de salida de los jobs. Si un paso en un job falla (por ejemplo, el comando para ejecutar tests devuelve un código de error distinto de cero), el job se marca como fallido, y esto se propaga al workflow completo. Así, el workflow falla si los tests no pasan, sin necesidad de lógica adicional.

Código en acción

Aquí tienes un ejemplo funcional de un workflow de GitHub Actions para una aplicación Node.js. Este archivo se guardaría en .github/workflows/test.yml en tu repositorio.

name: Run Tests on Push and PR

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '18'

    - name: Install dependencies
      run: npm ci

    - name: Run tests
      run: npm test

En este ejemplo, el paso Run tests ejecuta npm test, que corre los tests de Jest. Si los tests fallan, este comando devolverá un código de error no cero, haciendo que el step falle. GitHub Actions detecta esto y marca el job test como fallido, lo que a su vez hace que todo el workflow falle. Así, si haces un push con código que rompe los tests, verás una marca roja en GitHub, indicando que el workflow no pasó.

Errores comunes

  • No configurar el evento correcto: Si olvidas especificar on: [push, pull_request] o lo limitas demasiado, el workflow no se ejecutará cuando necesites, dejando pasar código no probado. Solución: Define claramente los branches y eventos relevantes para tu flujo de trabajo.
  • Asumir que los tests se ejecutan en silencio: Algunos entornos pueden no fallar automáticamente si los tests no pasan. Por ejemplo, si usas un script personalizado que no propaga códigos de error. Solución: Asegúrate de que el comando de tests (como npm test o pytest) devuelva un código de salida apropiado en caso de fallo.
  • Ignorar la caché de dependencias: En proyectos grandes, instalar dependencias desde cero cada vez puede ralentizar el workflow. Solución: Usa acciones como actions/cache para cachear node_modules o similares, acelerando las ejecuciones sin comprometer la confiabilidad.
  • No manejar entornos específicos: Si tus tests requieren variables de entorno o configuraciones especiales, olvidarlas puede causar fallos falsos. Solución: Define variables de entorno en el workflow usando env o secrets de GitHub.

Checklist de dominio

  • ¿Puedes crear un archivo YAML básico en .github/workflows/ que se active en push y pull request?
  • ¿Sabes configurar un job que instale dependencias y ejecute tests para tu stack tecnológico (ej., Node.js, Python, Java)?
  • ¿Entiendes cómo GitHub Actions detecta un fallo en un step y propaga el estado al workflow?
  • ¿Puedes verificar en la pestaña Actions de GitHub si un workflow falló debido a tests no exitosos?
  • ¿Sabes agregar caching para dependencias y optimizar el tiempo de ejecución del workflow?
  • ¿Eres capaz de personalizar el workflow para manejar múltiples jobs, como tests unitarios y de integración por separado?
  • ¿Puedes explicar por qué es crucial que el workflow falle ante tests fallidos, en lugar de solo generar un reporte?

Implementa un workflow de GitHub Actions que falle si los tests de una app Python no pasan

En este ejercicio, crearás un workflow desde cero para una aplicación Python que usa pytest. Sigue estos pasos:

  1. Crea un nuevo repositorio en GitHub o usa uno existente con una estructura básica de Python (un archivo app.py y un archivo test_app.py con al menos un test que pase y otro que falle inicialmente).
  2. En la raíz del repositorio, crea un directorio llamado .github/workflows si no existe.
  3. Dentro de .github/workflows, crea un archivo YAML llamado python-tests.yml.
  4. Configura el workflow para que se active en eventos de push a la rama main y en pull requests hacia main.
  5. Define un job llamado test que use el runner ubuntu-latest.
  6. Agrega steps para: a) Hacer checkout del código, b) Configurar Python 3.9, c) Instalar dependencias desde un archivo requirements.txt (puedes crear uno con pytest como dependencia), d) Ejecutar pytest para correr los tests.
  7. Guarda el archivo, haz commit y push a tu repositorio. Verifica en la pestaña Actions de GitHub que el workflow se ejecuta y falla si los tests no pasan.
  8. Corrige el test que falla en test_app.py y haz otro push. Confirma que el workflow ahora pasa.
Pistas
  • Recuerda que pytest devuelve un código de error si los tests fallan, lo que hará que el step falle automáticamente.
  • Puedes usar la acción actions/setup-python para configurar el entorno de Python.
  • Si no tienes un archivo requirements.txt, crea uno con 'pytest' como contenido para el paso de instalación.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.