Docker para QA: Containers para Testes e Ambientes

Testes Automatizados · 6 de julho de 2026

📖 4 min de leitura

Por Que Docker para QA?

  • Ambientes consistentes – Same in dev, CI, prod
    1. Isolamento – Testes não afetam sistema host
    2. Reproducibilidade – Resultados consistentes
    3. Escalabilidade – Múltiplos containers de teste
    4. CI/CD integration – Fáceis de automatizar

Dockerfile para Testes

Multi-Stage Build

# syntax=docker/dockerfile:1

# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# Stage 2: Test
FROM node:18-alpine AS test
WORKDIR /app

# Copy dependencies only (layer caching)
COPY package*.json ./
RUN npm ci

# Copy source
COPY . .

# Install test dependencies
RUN npm ci --prefix .

# Copy built artifacts
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules

# Run tests
CMD ["npm", "test"]

# Stage 3: Production
FROM node:18-alpine AS production
WORKDIR /app

COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./

USER node
EXPOSE 8080

CMD ["node", "dist/index.js"]

Python Tests

FROM python:3.11-slim

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends
build-essential
libpq-dev
&& rm -rf /var/lib/apt/lists/*

# Copy requirements first (layer caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY . .

# Run tests with coverage
CMD ["pytest", "-v", "--cov=src", "--cov-report=xml", "--cov-report=html"]


Docker Compose para Ambientes

Desenvolvimento Local

# docker-compose.yml
version: '3.8'

services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- DATABASE_URL=postgres://test:test@db:5432/test
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- .:/app
- /app/node_modules
command: npm run dev

db:
image: postgres:15-alpine
environment:
POSTGRES_DB: test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U test -d test"]
interval: 5s
timeout: 5s
retries: 5

cache:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data

test:
build:
context: .
dockerfile: Dockerfile.test
environment:
- DATABASE_URL=postgres://test:test@db:5432/test
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- ./test-results:/app/test-results
command: pytest -v --junitxml=/app/test-results/results.xml

volumes:
postgres_data:
redis_data:

CI Environment

# docker-compose.ci.yml
version: '3.8'

services:
app:
build:
context: .
target: test
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
environment:
DATABASE_URL: postgres://test:test@postgres:5432/test
REDIS_URL: redis://redis:6379
command: pytest -v --cov=src --cov-report=xml --cov-fail-under=80

postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
healthcheck:
test: ["CMD-SHELL", "pg_isready -U test"]
interval: 5s
timeout: 5s
retries: 5

redis:
image: redis:7-alpine


Testcontainers

# testcontainers_example.py
import pytest
from testcontainers.postgres import PostgresContainer
from testcontainers.redis import RedisContainer
from testcontainers.compose import DockerCompose
import psycopg2

@pytest.fixture(scope="module")
def postgres():
with PostgresContainer("postgres:15") as pg:
yield pg

@pytest.fixture(scope="module")
def redis():
with RedisContainer("redis:7") as rd:
yield rd

@pytest.fixture
def db_connection(postgres):
conn = psycopg2.connect(postgres.get_connection_url())
yield conn
conn.close()

def test_with_containers(postgres, redis):
"""Test usando bancos containerizados"""
# Use containers
db_url = postgres.get_connection_url()
redis_url = redis.get_connection_url()

# Your test logic here
conn = psycopg2.connect(db_url)
cursor = conn.cursor()
cursor.execute("SELECT version();")
result = cursor.fetchone()
assert "PostgreSQL" in result[0]


Docker para Selenium Grid

# selenium-grid.yml
version: '3.8'

services:
selenium-hub:
image: selenium/hub:4.15
ports:
- "4442:4442"
- "4443:4443"
- "4444:4444"
environment:
SE_EVENT_BUS_HOST: selenium-hub
SE_EVENT_BUS_PUBLISH_PORT: 4442
SE_EVENT_BUS_SUBSCRIBE_PORT: 4443

chrome:
image: selenium/node-chrome:4.15
depends_on:
- selenium-hub
environment:
SE_EVENT_BUS_HOST: selenium-hub
SE_EVENT_BUS_PUBLISH_PORT: 4442
SE_EVENT_BUS_SUBSCRIBE_PORT: 4443
SE_NODE_MAX_SESSIONS: 5
shm_size: '2gb'

firefox:
image: selenium/node-firefox:4.15
depends_on:
- selenium-hub
environment:
SE_EVENT_BUS_HOST: selenium-hub
SE_EVENT_BUS_PUBLISH_PORT: 4442
SE_EVENT_BUS_SUBSCRIBE_PORT: 4443
SE_NODE_MAX_SESSIONS: 3

edge:
image: selenium/node-edge:4.15
depends_on:
- selenium-hub
environment:
SE_EVENT_BUS_HOST: selenium-hub
SE_EVENT_BUS_PUBLISH_PORT: 4442
SE_EVENT_BUS_SUBSCRIBE_PORT: 4443
SE_NODE_MAX_SESSIONS: 3


Conclusão

Docker é essencial para QA moderno. As chaves são:

  1. Multi-stage builds – Imagens otimizadas
  2. Docker Compose – Ambientes completos
  3. Testcontainers – DBs containerizados para testes
  4. Layer caching – Builds mais rápidos
  5. CI integration – Automação simplificada