GitHub Actions for Test Automation
GitHub Actions is the most widely adopted CI/CD platform for open-source and enterprise projects. Its tight integration with GitHub repositories, marketplace of reusable actions, and simple YAML syntax make it the go-to platform for integrating automated test suites. This topic covers complete, production-ready GitHub Actions workflows for web, API, and mobile test automation.
Complete GitHub Actions Test Workflow
# ══════════════════════════════════════════════════════════════
# .github/workflows/test-suite.yml
# Production-ready CI workflow for a full test suite
# ══════════════════════════════════════════════════════════════
name: Test Suite
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
- cron: '0 2 * * *' # Nightly regression at 2:00 AM
env:
PYTHON_VERSION: '3.12'
NODE_VERSION: '20'
BASE_URL: ${{'{{'}} secrets.STAGING_BASE_URL }}
jobs:
# ── JOB 1: Unit Tests (fast — run on every push) ─────────────
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install Dependencies
run: pip install -r requirements-test.txt
- name: Run Unit Tests
run: pytest tests/unit/ -v --tb=short --junitxml=results/unit-tests.xml
- name: Upload Unit Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: unit-test-results
path: results/unit-tests.xml
# ── JOB 2: API Tests (medium) ─────────────────────────────────
api-tests:
name: API Tests
runs-on: ubuntu-latest
needs: unit-tests # Only run if unit tests pass
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install Dependencies
run: pip install -r requirements-test.txt
- name: Run API Tests
env:
API_AUTH_TOKEN: ${{ secrets.STAGING_API_TOKEN }}
run: |
pytest tests/api/ -v -n 4 # 4 parallel workers
--alluredir=./allure-results --junitxml=results/api-tests.xml -m "not slow"
- name: Upload Allure Results
if: always()
uses: actions/upload-artifact@v4
with:
name: allure-results-api
path: allure-results/
# ── JOB 3: E2E Tests (slower — needs a browser) ───────────────
e2e-tests:
name: E2E Tests (Playwright)
runs-on: ubuntu-latest
needs: api-tests
strategy:
matrix:
browser: [chromium, firefox] # Run on both browsers
fail-fast: false # Don't cancel other browser if one fails
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install Dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install ${{ matrix.browser }} --with-deps
- name: Run E2E Tests
run: npx playwright test --project=${{ matrix.browser }}
env:
BASE_URL: ${{ env.BASE_URL }}
- name: Upload Playwright Report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report-${{ matrix.browser }}
path: playwright-report/
retention-days: 14
# ── JOB 4: Security Scan ──────────────────────────────────────
security:
name: Security Scan (ZAP)
runs-on: ubuntu-latest
needs: unit-tests
steps:
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: ${{ env.BASE_URL }}
fail_action: true # Fail build on high-risk alerts
# ── JOB 5: Notify on completion ───────────────────────────────
notify:
name: Notify Results
runs-on: ubuntu-latest
needs: [unit-tests, api-tests, e2e-tests, security]
if: always()
steps:
- name: Notify Slack on Failure
if: failure()
uses: slackapi/slack-github-action@v1.26.0
with:
payload: |
{"text": "❌ Test Suite FAILED on ${{ github.ref }}. <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Results>"}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}Common Mistakes
- Running all jobs sequentially — independent jobs (unit, API, security) should run in parallel; sequential pipelines are 3x slower than necessary
- Hardcoding secrets in YAML — never put API keys, passwords, or base URLs in workflow files; use GitHub Secrets and reference as ${{ secrets.NAME }}
- Not uploading artifacts — test results and screenshots disappear when the runner terminates; always upload reports and Allure results
- Not using cache for dependencies — pip install and npm ci without caching adds 2-5 minutes per run; use actions/cache or setup-python's built-in cache
Tip
Tip
Practice GitHub Actions for Test Automation in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Playwright rising fast — modern API, auto-waits, all browsers
Practice Task
Note
Practice Task — (1) Write a working example of GitHub Actions for Test Automation from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with GitHub Actions for Test Automation is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready software testing code.
Key Takeaways
- GitHub Actions is the most widely adopted CI/CD platform for open-source and enterprise projects.
- Running all jobs sequentially — independent jobs (unit, API, security) should run in parallel; sequential pipelines are 3x slower than necessary
- Hardcoding secrets in YAML — never put API keys, passwords, or base URLs in workflow files; use GitHub Secrets and reference as ${{ secrets.NAME }}
- Not uploading artifacts — test results and screenshots disappear when the runner terminates; always upload reports and Allure results