CI/CD Integration

SpecTracer is designed from the ground up for CI pipelines. Zero infrastructure — just a CLI run producing a static HTML file you can publish as an artifact.

GitHub Actions

Add a step to your existing workflow to generate the SpecTracer report and upload it as an artifact:

.github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test-and-report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: astral-sh/setup-uv@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: uv sync

      - name: Run unit tests
        run: uv run pytest tests/unit --junitxml=reports/unit.xml

      - name: Run integration tests
        run: uv run pytest tests/integration --junitxml=reports/int.xml

      - name: Run E2E tests
        run: uv run behave features/ --format json -o reports/e2e.json

      - name: Generate SpecTracer report
        run: uv run python build_pyramid.py

      - name: Upload report as artifact
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report
          path: report.html
ℹ Report is self-contained The HTML file includes all CSS and JS inline. You can download it from the Actions run page and open it directly in a browser — no server needed.

PR Comment with Report Link

To make the report visible on pull requests, add a step that comments with a link to the artifact:

      - name: Comment PR
        uses: actions/github-script@v7
        if: github.event_name == 'pull_request'
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## SpecTracer Coverage Report\n\n[Download the report](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`
            })

GitLab CI

.gitlab-ci.yml
stages:
  - test
  - report

variables:
  UV_PYTHON: "3.12"

unit-tests:
  stage: test
  script:
    - uv run pytest tests/unit --junitxml=reports/unit.xml
  artifacts:
    paths:
      - reports/unit.xml

integration-tests:
  stage: test
  script:
    - uv run pytest tests/integration --junitxml=reports/int.xml
  artifacts:
    paths:
      - reports/int.xml

e2e-tests:
  stage: test
  script:
    - uv run behave features/ --format json -o reports/e2e.json
  artifacts:
    paths:
      - reports/e2e.json

spectracer-report:
  stage: report
  needs:
    - unit-tests
    - integration-tests
    - e2e-tests
  script:
    - uv sync
    - uv run python build_pyramid.py
  artifacts:
    paths:
      - report.html
    expose_as: Coverage Report

Jenkins

Jenkinsfile (Declarative)
pipeline {
    agent any

    stages {
        stage('Install') {
            steps {
                sh 'uv sync'
            }
        }
        stage('Run Tests') {
            parallel {
                stage('Unit') {
                    steps {
                        sh 'uv run pytest tests/unit --junitxml=reports/unit.xml'
                    }
                }
                stage('Integration') {
                    steps {
                        sh 'uv run pytest tests/integration --junitxml=reports/int.xml'
                    }
                }
                stage('E2E') {
                    steps {
                        sh 'uv run behave features/ --format json -o reports/e2e.json'
                    }
                }
            }
        }
        stage('Generate Report') {
            steps {
                sh 'uv run python build_pyramid.py'
            }
        }
    }
    post {
        success {
            archiveArtifacts artifacts: 'report.html',
                fingerprint: true
        }
    }
}

Team Workflows

🎓 Onboarding a New Project

  1. Write feature files — your team's QA or product owner creates .feature files describing every business scenario. Each scenario gets a unique tag like @FC-001.
  2. Add tags to tests — developers add the matching tags to their unit/integration/E2E tests. A quick PR review ensures tag naming consistency.
  3. Set up the config — create spectracer.config.json pointing at your feature files and test outputs.
  4. Add to CI — add the SpecTracer step to your pipeline. The report becomes part of every build.

📈 Using the Report in a Sprint

  • Daily standup: Pull up the latest report. The headline coverage % is a great conversation starter. "We dropped from 78% to 72% — did we add scenarios without tests?"
  • Sprint review: Show the trend. Are you adding more scenarios than tests? Is the pyramid inverting?
  • PR reviews: If you gate PRs on error_on_failure: true, the report shows exactly which scenarios lost coverage.

📜 Tag Naming Convention

Establish a consistent tag naming scheme across your team:

PatternExampleUse
@FC-<N>@FC-42Feature-case ID — unique per scenario
@<module>@billingCross-cutting module tag
@<type>@regression, @smokeTest type classification

Best Practices

✓ Start small, expand gradually Begin with just E2E coverage (@require-e2e is the default). Add unit and integration requirements as you build out those test layers.
✓ Commit the config file spectracer.config.json belongs in version control. It defines your team's coverage contract.
⚠ Ignore the report Add report.html to .gitignore. It's a build artifact generated by CI.
ℹ Use module-scoped requirements for microservices If your team owns a single service in a multi-service repo, use @require-unit:my-service to ensure your service's unit tests cover its scenarios.

The Standup Metric

SpecTracer's headline metric — Tested: X / Y scenarios (Z%) — is designed for daily standup discussion. Unlike code coverage (which measures lines executed), this metric measures business scenario coverage:

Teams that use SpecTracer find themselves discussing coverage in standup naturally: "Our coverage dropped from 85% to 78% this sprint — let's add tests for the new billing scenarios before the sprint ends."