Claude-skill-registry implement-step-definitions
Implement step definitions for Gherkin scenarios, translating Given/When/Then into executable test code. Use after write-scenario when scenarios are defined but step definitions are missing.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/implement-step-definitions" ~/.claude/skills/majiayu000-claude-skill-registry-implement-step-definitions && rm -rf "$T"
skills/data/implement-step-definitions/SKILL.mdimplement-step-definitions
Skill Type: Actuator (BDD Workflow) Purpose: Translate Given/When/Then scenarios into executable test code Prerequisites:
- Feature file exists with Gherkin scenarios
- BDD framework available (Cucumber, Behave, etc.)
Agent Instructions
You are in the STEP DEFINITIONS phase of BDD (SCENARIO → STEP DEFINITIONS → IMPLEMENT → REFACTOR).
Your goal is to translate Given/When/Then steps into executable test code (step definitions).
Workflow
Step 1: Read Feature File
Parse the Gherkin scenarios:
- What Given/When/Then steps exist?
- Which steps are reusable across scenarios?
- What test fixtures are needed?
Example:
# features/authentication.feature Scenario: Successful login Given I am a registered user with email "user@example.com" And my password is "SecurePassword123!" When I enter email "user@example.com" And I enter password "SecurePassword123!" And I click the "Login" button Then I should see "Welcome back" # Unique steps needed: # - Given I am a registered user with email {email} # - And my password is {password} # - When I enter email {email} # - And I enter password {password} # - And I click the {button} button # - Then I should see {message}
Step 2: Determine Step Definition File Location
Follow BDD framework conventions:
Cucumber (JavaScript/TypeScript):
features/step_definitions/authentication_steps.js features/step_definitions/authentication_steps.ts
Behave (Python):
features/steps/authentication_steps.py
Cucumber (Java):
src/test/java/steps/AuthenticationSteps.java
Step 3: Write Step Definitions
Template for Python (Behave):
# features/steps/authentication_steps.py # Validates: <REQ-ID> # Business Rules: BR-001, BR-002, BR-003 from behave import given, when, then from src.auth.authentication import login from test_helpers import create_test_user, get_ui_element # Test fixtures _test_users = {} _login_result = None _ui_state = {} @given('I am a registered user with email "{email}"') def step_impl(context, email): """Create a test user with specified email""" # Validates: <REQ-ID> user = create_test_user(email=email) _test_users[email] = user context.user = user @given('my password is "{password}"') def step_impl(context, password): """Set user's password""" context.user.set_password(password) @when('I enter email "{email}"') def step_impl(context, email): """User enters email in login form""" _ui_state['email_input'] = email @when('I enter password "{password}"') def step_impl(context, password): """User enters password in login form""" _ui_state['password_input'] = password @when('I click the "{button}" button') def step_impl(context, button): """User clicks a button""" if button == "Login": # Perform login action global _login_result email = _ui_state.get('email_input') password = _ui_state.get('password_input') _login_result = login(email, password) @then('I should see "{message}"') def step_impl(context, message): """Verify user sees expected message""" # This would check UI in real implementation # For now, check login result if message == "Welcome back": assert _login_result.success == True else: assert _login_result.error == message @then('I should be redirected to the dashboard') def step_impl(context): """Verify user is redirected""" assert _login_result.success == True # In real implementation, check URL or page content
Key elements:
- ✅ Tag with REQ-* key in comments
- ✅ One step definition per unique step
- ✅ Parameterized step definitions (use
){parameter} - ✅ Reusable across scenarios
- ✅ Clear docstrings explaining step purpose
Template for JavaScript (Cucumber):
// features/step_definitions/authentication_steps.js // Validates: <REQ-ID> // Business Rules: BR-001, BR-002, BR-003 const { Given, When, Then } = require('@cucumber/cucumber'); const { login } = require('../../src/auth/authentication'); const assert = require('assert'); let testUser; let loginResult; let uiState = {}; Given('I am a registered user with email {string}', function(email) { // Validates: <REQ-ID> testUser = createTestUser(email); }); Given('my password is {string}', function(password) { testUser.setPassword(password); }); When('I enter email {string}', function(email) { uiState.email = email; }); When('I enter password {string}', function(password) { uiState.password = password; }); When('I click the {string} button', function(button) { if (button === 'Login') { loginResult = login(uiState.email, uiState.password); } }); Then('I should see {string}', function(message) { if (message === 'Welcome back') { assert.strictEqual(loginResult.success, true); } else { assert.strictEqual(loginResult.error, message); } });
Step 4: Run Scenarios (Expect FAILURE)
Run BDD framework:
# Behave (Python) behave features/authentication.feature # Cucumber (JavaScript) npm run cucumber # Cucumber (Java) mvn test -Dcucumber.options="features/authentication.feature"
Expected output:
Feature: User Login Background: Given the application is running PASSED And I am on the login page PASSED Scenario: Successful login Given I am a registered user PASSED And my password is "SecurePassword123!" PASSED When I enter email "user@example.com" PASSED And I enter password "SecurePassword123!" PASSED And I click the "Login" button FAILED AttributeError: 'NoneType' object has no attribute 'success' (login function doesn't exist yet)
✅ This is GOOD! Steps execute but implementation doesn't exist yet.
Step 5: Commit Step Definitions
Create commit:
git add features/steps/authentication_steps.py git commit -m "STEP DEF: Add step definitions for <REQ-ID> Implement step definitions for user login scenarios. Step definitions: - Given steps: Set up test users and state - When steps: Simulate user actions - Then steps: Verify expected outcomes Steps: 12 step definitions (scenarios fail - no implementation yet) Validates: <REQ-ID> "
Output Format
When you complete the STEP DEFINITIONS phase, show:
[STEP DEFINITIONS Phase - <REQ-ID>] Feature File: features/authentication.feature Step Definitions Created: Given steps (4): ✓ I am a registered user with email {email} ✓ my password is {password} ✓ the application is running ✓ I am on the login page When steps (5): ✓ I enter email {email} ✓ I enter password {password} ✓ I click the {button} button ✓ I attempt to login with email {email} and password {password} Then steps (3): ✓ I should see {message} ✓ I should be redirected to the dashboard ✓ my account should be locked Step Definition File: features/steps/authentication_steps.py (12 steps, 142 lines) Running scenarios... Scenario: Successful login FAILED (no implementation) Scenario: Login fails invalid email FAILED (no implementation) Scenario: Login fails short password FAILED (no implementation) Scenario: Account locks after 3 fails FAILED (no implementation) Result: 5 scenarios FAILED ✓ (expected - implementation missing) Commit: STEP DEF: Add step definitions for <REQ-ID> ✅ STEP DEFINITIONS Phase Complete! Next: Invoke implement-feature skill to implement functionality
Prerequisites Check
Before invoking this skill, ensure:
- Feature file exists (from write-scenario)
- BDD framework available
- Step definitions directory exists
If prerequisites not met:
- No feature file → Invoke
skill firstwrite-scenario - No BDD framework → Ask user which to install
Next Steps
After STEP DEFINITIONS phase completes:
- Do NOT implement feature yet (that's next phase)
- Invoke
skill to implement functionalityimplement-feature - Scenarios should PASS after implementation
Step Definition Patterns
Parameterized Steps
✅ Good (reusable):
@given('I am a user with email "{email}"') def step_impl(context, email): context.user = create_user(email)
❌ Bad (hard-coded):
@given('I am a user with email user@example.com') def step_impl(context): context.user = create_user('user@example.com')
Shared Context
Use
object to share state between steps:context
@given('I am logged in') def step_impl(context): context.user = login() @when('I view my profile') def step_impl(context): context.profile = get_profile(context.user) # Uses user from Given @then('I should see my email') def step_impl(context): assert context.profile.email == context.user.email
Test Helpers
Extract common logic to helpers:
# test_helpers.py def create_test_user(email, password="DefaultPass123!"): """Create a user for testing""" user = User(email=email) user.set_password(password) user.save() return user def cleanup_test_users(): """Delete all test users""" User.delete_where(email__startswith="test_")
Notes
Why step definitions separate from implementation?
- Step definitions = test automation code
- Implementation = production code
- Separation of concerns (test vs production)
- Step definitions can test multiple implementations
Step definition reusability:
- Same step definitions can test multiple features
- Parameterized steps increase reusability
- Keep step definitions simple and focused
Homeostasis Goal:
desired_state: all_steps_defined: true steps_reusable: true scenarios_executable: true
"Excellence or nothing" 🔥