Skip to content

E2E Testing

Test full workflows in real clusters with CI/CD integration.


GitHub Actions Workflow

name: E2E Tests

on: [pull_request]

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'

      - uses: helm/kind-action@v1
        with:
          cluster_name: test-cluster

      - name: Build CLI
        run: go build -o myctl ./main.go

      - name: Run E2E tests
        run: |
          kubectl create namespace e2e-test
          kubectl -n e2e-test apply -f test/fixtures/
          ./myctl orchestrate --namespace e2e-test --dry-run

E2E Test Script

Always Clean Up

Use trap cleanup EXIT to ensure test namespaces are deleted even when tests fail. Orphaned resources waste cluster resources and can cause conflicts in later runs.

#!/bin/bash
# test/e2e/run.sh
set -euo pipefail

NAMESPACE="e2e-test-$(date +%s)"

cleanup() {
    kubectl delete namespace "$NAMESPACE" --ignore-not-found
}
trap cleanup EXIT

echo "Creating test namespace: $NAMESPACE"
kubectl create namespace "$NAMESPACE"

echo "Deploying test fixtures..."
kubectl -n "$NAMESPACE" apply -f test/fixtures/

echo "Waiting for deployments..."
kubectl -n "$NAMESPACE" wait --for=condition=available deployment --all --timeout=60s

echo "Running orchestrate command..."
./myctl orchestrate --namespace "$NAMESPACE"

echo "Verifying results..."
RESTARTS=$(kubectl -n "$NAMESPACE" get pods -o jsonpath='{.items[*].status.containerStatuses[*].restartCount}')
if [[ "$RESTARTS" != "0 0 0" ]]; then
    echo "ERROR: Unexpected restart counts: $RESTARTS"
    exit 1
fi

echo "E2E tests passed!"

Test Fixtures

# test/fixtures/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-app
  labels:
    app: test-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-app
  template:
    metadata:
      labels:
        app: test-app
    spec:
      containers:
        - name: main
          image: nginx:alpine
          resources:
            limits:
              cpu: 50m
              memory: 64Mi

Matrix Testing

Test across multiple Kubernetes versions:

name: E2E Matrix

on: [pull_request]

jobs:
  e2e:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        k8s-version:
          - v1.28.0
          - v1.29.0
          - v1.30.0
      fail-fast: false
    steps:
      - uses: actions/checkout@v4

      - uses: helm/kind-action@v1
        with:
          node_image: kindest/node:${{ matrix.k8s-version }}
          cluster_name: test-cluster

      - name: Build and Test
        run: |
          go build -o myctl ./main.go
          ./test/e2e/run.sh

Smoke Tests in Production

For production verification without risk:

#!/bin/bash
# Smoke test - read-only operations only
set -euo pipefail

echo "Running smoke tests..."

# Check version
./myctl version

# Check without making changes
./myctl check --json

# List without restart
./myctl select --output json

echo "Smoke tests passed!"

Best Practices

Practice Description
Isolated namespaces Create unique namespaces per test run
Cleanup on exit Always clean up, even on failure
Timeouts Set reasonable timeouts for resource waits
Dry run first Test with --dry-run before real operations
Matrix testing Test across multiple Kubernetes versions

E2E tests catch workflow bugs that integration tests miss.

Comments