CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/bdd-step-library-curator

Keeps a BDD step-definition library DRY across a Cucumber / Behave / Reqnroll project - inventories every step definition, detects duplicates (different patterns matching the same intent), recommends canonical consolidations, reorganizes steps by domain, publishes a step-library README the team greps for "is there already a step for X?" before authoring new ones, and builds a scenario coverage map that fingerprints new Gherkin scenarios against the live suite to classify each as duplicate, partial overlap, or genuine gap before any test is authored. Use when a BDD project's step count grows past ~50, on a quarterly step-library review, when a new engineer is about to write a duplicate step, or when fresh .feature files need a covered-already check.

73

Quality

92%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

step-extraction-and-overlap.mdreferences/

Step extraction, overlap detection, and the pre-merge gate

Deep reference for the bdd-step-library-curator SKILL. Consult when running the inventory against a specific BDD runner, wiring the programmatic overlap detector, or adding the pre-merge new-step CI gate.

Per-runner step extraction

Each BDD runner declares steps with its own annotation syntax; extract the raw patterns per runner and combine the output into a single list.

# Cucumber-JVM
grep -rE '@(Given|When|Then|And|But)\(' src/test/java/ | \
  sed -E 's/.*@(Given|When|Then|And|But)\("([^"]*)".*/\2/'

# Behave
grep -rE '^@(given|when|then|step)\(' features/steps/ | \
  sed -E 's/.*@(given|when|then|step)\("([^"]*)".*/\2/'

# Reqnroll / SpecFlow
grep -rE '\[(Given|When|Then|And|But)\(' Tests/Steps/ | \
  sed -E 's/.*\[(Given|When|Then|And|But)\("([^"]*)".*/\2/'

Each command emits one step pattern per line; feed the combined list into the overlap detector below.

Programmatic overlap detection

Normalize each pattern (lowercase, strip articles, collapse every parameter to a single placeholder) and group patterns that collapse to the same normalized form. Any group of size greater than one is a candidate duplicate cluster.

# scripts/step-overlap.py
import re

def normalize(pattern):
    """Lower; strip articles; remove parameter type hints."""
    p = pattern.lower()
    p = re.sub(r'\b(a|an|the)\b', '', p)
    p = re.sub(r'\{[^}]+\}', '{var}', p)
    p = re.sub(r'\s+', ' ', p).strip()
    return p

steps = [...]   # from the extraction step

normalized = {}
for s in steps:
    n = normalize(s['pattern'])
    normalized.setdefault(n, []).append(s)

for n, group in normalized.items():
    if len(group) > 1:
        print(f"Likely duplicates ({len(group)}):")
        for s in group:
            print(f"  {s['pattern']} - {s['file']}:{s['line']}")

The detector is a heuristic - review each cluster before consolidating, since some collisions are legitimately distinct steps.

Pre-merge new-step gate

A CI check that warns (does not block) whenever a PR adds new step definitions, forcing the author to confirm the step is not already in the library.

# scripts/check-new-steps.sh
NEW_STEPS=$(git diff --diff-filter=A origin/main...HEAD -- '**/steps/*.py' '**/Steps/*.cs' '**/steps/*.java' \
  | grep -E '^\+' | grep -E '@(Given|When|Then)' | wc -l)

if [ $NEW_STEPS -gt 0 ]; then
  echo "::warning::This PR adds $NEW_STEPS new step definitions."
  echo "Before merging, verify these aren't duplicates of existing steps."
  echo "Run: bash scripts/step-overlap.py"
fi

The warning is intentionally non-blocking - it forces acknowledgment of a new step without stopping legitimately-new ones.

SKILL.md

tile.json