Using ChatGPT to Audit Your Test Coverage
Most test suites grow by accretion. A feature ships, someone writes a scenario, it gets merged, and the suite expands — but rarely in a structured way. Six months later you have 400 Gherkin scenarios that cover the happy path in exhaustive detail and almost nothing around edge cases, error boundaries, or cross-feature interactions. Coverage reports tell you which lines executed; they say nothing about which behaviors you never thought to test.
That's the gap ChatGPT can help close — not by generating test code for you, but by acting as a structured reviewer of your requirement-to-scenario mapping. Feed it your feature files, your OpenAPI spec, or your user stories and ask it to reason about what's missing. The output is a prioritized list of untested behaviors, not a green percentage on a dashboard.
By the end of this article you'll have a repeatable prompt-and-pipeline pattern for running a coverage audit against a real Behave or Cucumber-JVM 7 suite, know where the model's reasoning breaks down, and understand which gaps it reliably finds versus which ones still require a human with domain context.
Smarter API Test Automation — Python, Behave, VS Code, AI with GitHub Copilot & CI/CD Pipelines. Complete in a Weekend!
What a Behavioral Coverage Audit Actually Measures
Line coverage and branch coverage measure code execution. Behavioral coverage measures whether your test suite encodes the decisions your system is supposed to make. A checkout flow with 95% line coverage can still have zero scenarios for concurrent session conflicts, partial payment failures, or cart expiry during payment processing — all real defect vectors that a line-coverage tool will never surface because the code paths exist and execute during other tests.
A ChatGPT-assisted audit treats your feature files (or Pytest test IDs, or Cypress 13 spec descriptions) as a corpus and compares them against a specification source — an OpenAPI 3.1 doc, a Confluence requirements page, a Jira epic, or even a plain-English description of the domain. The model reasons over the delta: what behaviors are described in the spec that have no corresponding scenario? It doesn't run your code. It reads your intent, and that's precisely what makes it useful at this layer of the test architecture, where static analysis tools are blind.
Building a Repeatable Audit Pipeline with ChatGPT
The audit has three mechanical steps: extract a normalized representation of your existing scenarios, feed it alongside the specification to the model with a structured prompt, and parse the response into actionable tickets or feature file stubs. Here's what that looks like against a Behave suite.
First, extract scenario titles and tags into a single text block. A small Python script handles this cleanly:
# extract_scenarios.py — requires behave 1.2.6+
import os, json
from behave.parser import Parser
parser = Parser()
scenarios = []
for root, _, files in os.walk("features/"):
for f in files:
if f.endswith(".feature"):
path = os.path.join(root, f)
feature = parser.parse(open(path).read(), filename=path)
for scenario in feature.scenarios:
scenarios.append({
"feature": feature.name,
"scenario": scenario.name,
"tags": scenario.tags,
})
print(json.dumps(scenarios, indent=2))
Pipe that JSON alongside your OpenAPI spec into a ChatGPT API call using a system prompt that constrains the model's role. Vague prompts produce vague output; this one doesn't:
# audit_coverage.py — openai>=1.14.0
from openai import OpenAI
import json, pathlib
client = OpenAI()
scenarios_json = pathlib.Path("scenarios.json").read_text()
openapi_yaml = pathlib.Path("openapi.yaml").read_text()
system_prompt = """
You are a senior SDET auditing behavioral test coverage.
Given a JSON list of existing Gherkin scenarios and an OpenAPI 3.1 spec,
identify behaviors described in the spec that have NO corresponding scenario.
For each gap, output:
- endpoint or domain behavior
- specific missing condition (e.g., 4xx response, concurrent request, boundary value)
- suggested Gherkin scenario title
Return ONLY a JSON array. No prose.
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"SCENARIOS:\n{scenarios_json}\n\nSPEC:\n{openapi_yaml}"}
],
temperature=0.2, # low temp = more deterministic gap analysis
response_format={"type": "json_object"},
)
gaps = json.loads(response.choices[0].message.content)
print(json.dumps(gaps, indent=2))
Temperature 0.2 matters here. Higher values cause the model to hallucinate scenarios that already exist in your suite under different phrasing — a false positive that wastes triage time. With a mid-sized suite (~300 scenarios) and a 40-endpoint OpenAPI spec, a single call costs roughly $0.04 on gpt-4o and returns a gap list in under 10 seconds. In one internal audit run against a payments service, this surfaced 23 untested error-response behaviors across 6 endpoints — conditions the team confirmed were real gaps, not hallucinations. That's the signal worth chasing.
Wire this into GitHub Actions so it runs on every PR that touches a .feature file or the OpenAPI spec:
# .github/workflows/coverage-audit.yml
name: BDD Coverage Audit
on:
pull_request:
paths:
- "features/**/*.feature"
- "openapi.yaml"
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install behave openai
- run: python extract_scenarios.py > scenarios.json
- run: python audit_coverage.py > gaps.json
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- uses: actions/upload-artifact@v4
with:
name: coverage-gaps
path: gaps.json
The artifact gives reviewers a machine-readable list of gaps attached to the PR. You don't need to auto-fail the build on gap count — that creates perverse incentives to write thin scenarios just to silence the check. Use it as a review signal, not a gate.
Where the Audit Workflow Breaks Down in Practice
Feeding the model stale or ambiguous specs is the most common failure mode. If your OpenAPI doc diverges from production behavior — which happens in teams where the spec is written once and never updated — the audit compares your scenarios against fiction. The gaps it finds are real relative to the spec, not relative to the system. Fix the spec drift first, or explicitly tell the model which source of truth to prioritize. Claude's 200K context window makes it marginally better for very large specs, but the spec-drift problem is organizational, not contextual.
Treating the gap list as a backlog without triage is the second trap. The model doesn't know your risk model. It will flag a missing scenario for a deprecated endpoint with the same weight as a missing scenario for your payment confirmation flow. A five-minute triage pass — tagging each gap as P1/P2/skip — turns a 40-item list into 8 actionable items. Skip this step and the audit output becomes noise that nobody acts on, which poisons adoption. Build the triage step into your PR review process explicitly, not as an afterthought.
Myths About AI-Assisted Coverage That Will Slow You Down
Myth: ChatGPT can replace a coverage strategy. It can surface gaps against a known spec, but it has no visibility into runtime behavior, production logs, or incident history. The scenarios most worth writing often come from post-mortems, not from spec-to-scenario diffing. Use OpenTelemetry trace data or Grafana dashboards to identify which code paths fire most frequently in production, then cross-reference with the model's gap list. The intersection is your highest-value test investment. Neither source alone is sufficient.
Myth: Higher scenario count means better coverage. Teams that run this audit and immediately generate 50 new Gherkin scenarios from the gap list often make their suite worse — slower, noisier, and harder to maintain — without meaningfully reducing defect escape rate. The test pyramid is not scripture, but the underlying principle holds: a scenario that duplicates logic already covered by a Pytest unit test adds maintenance cost without adding signal. Audit output should inform what to test, not automatically become tests. Write the scenario when the behavior has no other coverage; skip it when a lower-level test already owns it.
A coverage audit is a one-time exercise until you automate it. The pipeline above makes it continuous. Once it's running on PRs, the next measurement worth adding is gap recurrence rate — how often the same behavioral category (error handling, concurrency, boundary values) keeps appearing in audit output across releases. A persistent pattern there points to a process gap upstream, not a testing gap downstream, and that's a conversation worth having with your product team.
Note: This article is for informational purposes only and is not a substitute for professional advice. If you need guidance on specific situations described in this article, consider consulting a qualified professional.