# Kubernetes e QA: Testes em Ambientes Containerizados

**Meta Description:** Aprenda a testar aplicações em Kubernetes: Helm, deployments, services, configmaps e como integrar testes ao ciclo de deploy em K8s.

---

## Kubernetes para QA

### Por Que Kubernetes?

- **Isolamento** - Cada ambiente isolado
- **Reproducibilidade** - Ambientes idênticos
- **Escalabilidade** - Teste com múltiplas réplicas
- **Orquestração** - Deploys atômicos

---

## Recursos Kubernetes

### Pod

```yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: api-test-pod
  labels:
    app: api
    env: test
spec:
  containers:
  - name: api
    image: api:latest
    ports:
    - containerPort: 8080
    env:
    - name: DATABASE_URL
      valueFrom:
        secretKeyRef:
          name: api-secrets
          key: database-url
    resources:
      requests:
        memory: "256Mi"
        cpu: "250m"
      limits:
        memory: "512Mi"
        cpu: "500m"
    readinessProbe:
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20
```

### Deployment

```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: api:v1.0.0
        ports:
        - containerPort: 8080
        env:
        - name: ENV
          value: "production"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
```

### Service

```yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: ClusterIP
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 8080
    name: http
```

---

## Helm - Gerenciamento de Charts

### Estrutura

```
myapp/
├── Chart.yaml
├── values.yaml
├── charts/
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── _helpers.tpl
│   └── tests/
│       └── test-connection.yaml
└── README.md
```

### Chart.yaml

```yaml
# Chart.yaml
apiVersion: v2
name: myapp
description: A Helm chart for MyApp
type: application
version: 1.0.0
appVersion: "1.0.0"
keywords:
  - web
  - api
home: https://myapp.com
maintainers:
  - name: DevOps Team
    email: devops@myapp.com
dependencies:
  - name: postgresql
    version: "12.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
```

### values.yaml

```yaml
# values.yaml
replicaCount: 3

image:
  repository: myapp/api
  tag: latest
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  hosts:
    - host: api.myapp.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: api-tls
      hosts:
        - api.myapp.com

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 256Mi

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

postgresql:
  enabled: true
  auth:
    database: myapp
    username: myapp
    password: changeme

tests:
  enabled: true
  image: curlimages/curl:latest
```

### Test Template

```yaml
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ include "myapp.fullname" . }}-test-connection"
  labels:
    helm.sh/hook: test
    helm.sh/hook-delete-policy: before-hook-creation
  annotations:
    "helm.sh/hook": test
spec:
  containers:
  - name: wget
    image: "{{ .Values.tests.image }}"
    command: ['sh', '-c']
    args:
      - |
        echo "Testing API health endpoint..."
        response=$(curl -f http://{{ include "myapp.fullname" . }}:{{ .Values.service.port }}/health || echo "FAILED")
        echo "Response: $response"
        if [ "$response" != "OK" ]; then
          exit 1
        fi
  restartPolicy: Never
```

---

## Testando no Kubernetes

### Testes de Integração com Kind

```bash
# Criar cluster Kind
kind create cluster --name qa-tests

# Deploy app
kubectl apply -f deployment.yaml

# Run tests
kubectl run test-runner --image=myapp/test-runner -- curl http://api-service/health

# Ver resultado
kubectl logs test-runner

# Cleanup
kind delete cluster --name qa-tests
```

### kubectl Testing Commands

```bash
# Verificar pods
kubectl get pods -l app=api

# Ver logs
kubectl logs -l app=api --tail=100

# Port-forward para teste local
kubectl port-forward svc/api-service 8080:80

# Executar testes
kubectl exec -it api-pod -- python -m pytest tests/

# Ver events
kubectl get events --sort-by='.lastTimestamp'
```

### Teste com cURL

```bash
#!/bin/bash
# test-api.sh

API_URL="http://api-service"

echo "Testing API endpoints..."

# Health check
echo "1. Health check..."
response=$(curl -s -o /dev/null -w "%{http_code}" $API_URL/health)
if [ "$response" != "200" ]; then
  echo "FAILED: Health check returned $response"
  exit 1
fi
echo "OK"

# Teste de endpoint
echo "2. GET /users..."
response=$(curl -s $API_URL/users)
if echo "$response" | grep -q "users"; then
  echo "OK"
else
  echo "FAILED"
  exit 1
fi

echo "All tests passed!"
```

---

## CI/CD com Kubernetes

### GitHub Actions

```yaml
# .github/workflows/k8s-tests.yml
name: Kubernetes Tests

on:
  push:
    branches: [main, develop]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup kubectl
        uses: azure/setup-kubectl@v3
      
      - name: Configure kubectl
        run: |
          echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
          export KUBECONFIG=kubeconfig
      
      - name: Deploy to test
        run: |
          helm upgrade --install myapp ./chart \
            --namespace test \
            --create-namespace \
            --values ./chart/values-test.yaml \
            --wait --timeout 5m
      
      - name: Wait for pods
        run: |
          kubectl wait --for=condition=ready pod -l app=myapp \
            -n test --timeout=300s
      
      - name: Run API tests
        run: |
          kubectl exec -n test deploy/myapp -- \
            python -m pytest tests/ -v --junit-xml=/tmp/results.xml
      
      - name: Run integration tests
        run: |
          kubectl run test-runner -n test \
            --image=myapp/test-runner \
            --rm -it --restart=Never \
            -- curl -f http://myapp/health
      
      - name: Collect test results
        uses: actions/upload-artifact@v4
        with:
          name: test-results
          path: /tmp/results.xml
      
      - name: Cleanup
        if: always()
        run: helm uninstall myapp -n test
```

---

## Conclusão

Kubernetes facilita testes em ambientes controlados. As chaves são:

1. **Containerização** - Ambientes reproduzíveis
2. **Helm charts** - Deploys versionados
3. **Test hooks** - Testes no ciclo de deploy
4. **CI/CD integration** - Automação completa
5. **Monitoring** - Observabilidade em testes
