Los tests que pasan localmente pero fallan en CI a menudo no son bugs en los tests: son diferencias de entorno entre versiones de Node, builds del navegador o dependencias del sistema que faltan. Un contenedor Docker corrige esto empaquetando Playwright, sus binarios de navegador y todas las dependencias en una sola imagen que corre de forma idéntica en una laptop, en la computadora de un compañero y en CI. Esta guía cubre cómo escribir un Dockerfile para Playwright, ejecutar tests en un contenedor localmente, integrar con GitHub Actions, y usar Docker Compose cuando los tests necesitan la aplicación y una base de datos corriendo junto a ellos.
Por qué los ingenieros QA necesitan Docker
Sin Docker
- Tus tests pasan localmente con Node 20, fallan en CI con Node 18
- La versión de Chrome en CI difiere de la de tu laptop
- Las variables de entorno están configuradas diferente en cada máquina
- Un nuevo integrante del equipo pasa un día entero para que los tests corran
Con Docker
Los tests corren en el mismo contenedor localmente y en CI. Todos usan las mismas versiones de Node, Chrome y dependencias. Para un nuevo integrante, docker compose up es suficiente: los tests corren en 2 minutos.
Conceptos clave
Imagen
Una imagen es un plano: una instantánea de solo lectura de un sistema de archivos con software instalado. Piénsala como una clase en código.
playwright/playwright:latest — una imagen con Playwright y navegadores preinstalados
node:20-alpine — Node.js 20 sobre Alpine Linux minimalContenedor
Un contenedor es una instancia en ejecución de una imagen. Múltiples contenedores pueden correr desde la misma imagen simultáneamente. Como crear múltiples objetos a partir de la misma clase.
Dockerfile
Instrucciones para construir una imagen personalizada. Partes de una imagen base y le agregas tus archivos y configuración.
Docker Compose
Una herramienta para ejecutar múltiples contenedores juntos. Tus tests pueden necesitar un servidor web y una base de datos corriendo: Compose los inicia a todos con un solo comando.
Tu primer Dockerfile para Playwright
Playwright provee imágenes Docker oficiales con navegadores preinstalados:
# Dockerfile
FROM mcr.microsoft.com/playwright:v1.44.0-jammy
# Establecer el directorio de trabajo dentro del contenedor
WORKDIR /app
# Copiar los archivos de dependencias primero (optimización de caché)
COPY package.json package-lock.json ./
# Instalar dependencias de Node
RUN npm ci
# Copiar el resto del proyecto
COPY . .
# Comando por defecto: ejecutar todos los tests
CMD ["npx", "playwright", "test"]Construir la imagen
docker build -t my-playwright-tests .Ejecutar los tests
docker run my-playwright-testsChrome, Firefox y WebKit están todos dentro del contenedor. No se necesita instalar ningún navegador en la máquina host.
Ejecutar tests con Docker
Ejecución básica
# Ejecutar todos los tests
docker run my-playwright-tests
# Ejecutar un archivo de test específico
docker run my-playwright-tests npx playwright test tests/login.spec.ts
# Ejecutar con variable de entorno
docker run -e BASE_URL=https://staging.myapp.com my-playwright-tests
# Montar directorio local (para ver los resultados de los tests)
docker run -v $(pwd)/playwright-report:/app/playwright-report my-playwright-testsGuardar los resultados de los tests
El sistema de archivos del contenedor desaparece cuando el contenedor se detiene. Usa volúmenes montados para guardar los reportes:
docker run \
-v $(pwd)/playwright-report:/app/playwright-report \
-v $(pwd)/test-results:/app/test-results \
my-playwright-testsDespués de la ejecución, playwright-report/ aparece en tu máquina local.
Docker Compose para testing full stack
El testing real a menudo significa que la aplicación bajo prueba también necesita estar corriendo. Compose inicia todo junto.
# docker-compose.yml
version: '3.8'
services:
# La aplicación que estás testeando
app:
image: myapp:latest
ports:
- "3000:3000"
environment:
- NODE_ENV=test
- DATABASE_URL=postgresql://postgres:postgres@db:5432/testdb
depends_on:
db:
condition: service_healthy
# Base de datos
db:
image: postgres:16
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: testdb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
# Tests de Playwright
tests:
build: .
environment:
- BASE_URL=http://app:3000
depends_on:
- app
volumes:
- ./playwright-report:/app/playwright-report
- ./test-results:/app/test-resultsEjecutar todo
docker compose up --exit-code-from testsEsto inicia la base de datos, espera a que esté sana, inicia la aplicación, ejecuta los tests, devuelve el código de salida de los tests (para que CI sepa si pasaron o fallaron) y para los contenedores.
Optimizar el Dockerfile
El caché de capas hace que las reconstrucciones sean rápidas. La regla clave: pones lo que cambia con menos frecuencia arriba.
FROM mcr.microsoft.com/playwright:v1.44.0-jammy
WORKDIR /app
# 1. Copiar archivos de dependencias (cambian raramente)
COPY package.json package-lock.json ./
# Esta capa queda en caché hasta que cambia package.json
RUN npm ci
# 2. Copiar el resto (cambia en cada commit)
COPY . .
CMD ["npx", "playwright", "test"]Si solo cambiaste archivos de tests, Docker reutiliza la capa npm ci del caché. Tiempo de build: segundos en lugar de minutos.
Integración con CI/CD
GitHub Actions
# .github/workflows/playwright.yml
name: Playwright Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Construir imagen de tests
run: docker build -t playwright-tests .
- name: Ejecutar tests
run: |
docker run \
-v ${{ github.workspace }}/playwright-report:/app/playwright-report \
-e BASE_URL=${{ secrets.STAGING_URL }} \
playwright-tests
- name: Subir reporte
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/GitLab CI
# .gitlab-ci.yml
test:
image: docker:latest
services:
- docker:dind
script:
- docker build -t tests .
- docker run
-v $(pwd)/playwright-report:/app/playwright-report
-e BASE_URL=$STAGING_URL
tests
artifacts:
when: always
paths:
- playwright-report/Comandos Docker útiles para QA
# Listar contenedores en ejecución
docker ps
# Listar todas las imágenes
docker images
# Detener todos los contenedores en ejecución
docker stop $(docker ps -q)
# Eliminar todos los contenedores detenidos
docker container prune
# Eliminar imágenes no usadas
docker image prune
# Ver los logs de un contenedor en tiempo real
docker logs -f <container-id>
# Abrir una shell dentro de un contenedor en ejecución (ideal para depuración)
docker exec -it <container-id> /bin/bash
# Ejecutar un contenedor de forma interactiva
docker run -it my-playwright-tests /bin/bashDepurar dentro de un contenedor
Cuando los tests solo fallan dentro del contenedor:
# Iniciar el contenedor con shell en lugar de tests
docker run -it my-playwright-tests /bin/bash
# Ahora estás dentro del contenedor
# Verificar qué está instalado
node --version
npx playwright --version
# Ejecutar tests manualmente
npx playwright test tests/login.spec.ts --headed --debug
# Verificar variables de entorno
env | grep BASE_URLLos problemas más frecuentes son BASE_URL apuntando a localhost (funciona en el host, falla en el contenedor: usa el nombre del servicio en su lugar), variables de entorno faltantes, y permisos de archivos cuando los archivos creados fuera del contenedor son propiedad de root dentro de él.
La imagen Docker oficial de Playwright
# Descargar la imagen oficial de Playwright
docker pull mcr.microsoft.com/playwright:v1.44.0-jammy
# Ver qué tiene adentro
docker run -it mcr.microsoft.com/playwright:v1.44.0-jammy /bin/bash
# Verificar los navegadores instalados
npx playwright install --listv1.44.0-jammy corresponde a una versión específica de Playwright sobre Ubuntu 22.04 (Jammy). latest es la última versión pero puede romperse cuando Playwright se actualiza. Siempre fija una versión específica en producción.
Resumen
| Concepto | Qué es |
|----------|--------|
| Imagen | Plano con software preinstalado |
| Contenedor | Instancia en ejecución de una imagen |
| Dockerfile | Instrucciones para construir una imagen personalizada |
| Docker Compose | Ejecutar múltiples contenedores juntos |
| Volumen montado | Compartir archivos entre host y contenedor |
Para Playwright específicamente:
1. Usa mcr.microsoft.com/playwright como imagen base: incluye los navegadores
2. Monta los directorios de reportes para que los resultados sobrevivan cuando el contenedor se detenga
3. Usa Compose para iniciar la aplicación y los tests juntos
4. Fija versiones de imagen: latest causa roturas inesperadas