Modern QA2026Implementation in CI/CD — tiles
Log inJoin
74 / 108 · 03 Agentic Testing Architectures · The Dead Man's Switch Pattern← prev⊞ allnext →☰ Read as one page

10.2Implementation in CI/CD

The Dead Man's Switch lives outside the agent and harness. It is configured at the CI runner level:

GitHub Actions

- name: Run agentic tests
  timeout-minutes: 15           # Hard CI-level timeout
  env:
    AGENT_MAX_STEPS: 30
    AGENT_MAX_TOKENS: 50000
    AGENT_ALLOWED_DOMAINS: "staging.myapp.com,api.staging.myapp.com"
  run: |
    python -m pytest tests/agentic/ \
      --timeout=300 \            # Per-test timeout (pytest-timeout)
      --agent-budget=$AGENT_MAX_TOKENS

The layered timeout structure:

Layer 1: Per-action timeout (30s)
  → Catches: hung browser, slow element lookup
  → Set by: the harness (action-level)

Layer 2: Per-test timeout (300s / 5 min)
  → Catches: stuck agent loop, slow LLM response chain
  → Set by: pytest-timeout plugin

Layer 3: CI job timeout (15 min)
  → Catches: harness hang, process deadlock, zombie processes
  → Set by: GitHub Actions timeout-minutes

Layer 4: CI workflow timeout (60 min)
  → Catches: entire workflow stuck (multiple jobs)
  → Set by: GitHub Actions workflow-level timeout

GitLab CI

agentic_tests:
  timeout: 15 minutes
  variables:
    AGENT_MAX_STEPS: "30"
    AGENT_MAX_TOKENS: "50000"
  script:
    - python -m pytest tests/agentic/ --timeout=300
  after_script:
    - python scripts/cleanup_agent_processes.py

Jenkins

pipeline {
    options {
        timeout(time: 15, unit: 'MINUTES')
    }
    stages {
        stage('Agentic Tests') {
            steps {
                sh '''
                    timeout 300 python -m pytest tests/agentic/ \
                        --timeout=120
                '''
            }
            post {
                always {
                    sh 'pkill -f "playwright-cli" || true'
                    sh 'pkill -f "chromedriver" || true'
                }
            }
        }
    }
}