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:
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
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
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
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
- Write feature files — your team's QA or product owner creates
.featurefiles describing every business scenario. Each scenario gets a unique tag like @FC-001. - Add tags to tests — developers add the matching tags to their unit/integration/E2E tests. A quick PR review ensures tag naming consistency.
- Set up the config — create
spectracer.config.jsonpointing at your feature files and test outputs. - 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:
| Pattern | Example | Use |
|---|---|---|
@FC-<N> | @FC-42 | Feature-case ID — unique per scenario |
@<module> | @billing | Cross-cutting module tag |
@<type> | @regression, @smoke | Test type classification |
Best Practices
@require-e2e is the default). Add unit and integration requirements as you build out those test layers.
spectracer.config.json belongs in version control. It defines your team's coverage contract.
report.html to .gitignore. It's a build artifact generated by CI.
@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:
- It's meaningful to product managers — "we haven't tested the password reset flow yet"
- It's actionable for developers — "scenario @FC-43 needs a unit test"
- It's visible to leadership — a single number that reflects the team's testing health
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."