Files
requirements-to-gherkin-cli/src/nl2gherkin/exporters/pytest_bdd.py

142 lines
3.6 KiB
Python

"""pytest-bdd exporter for pytest projects."""
from typing import Dict, List
from nl2gherkin.exporters.base import BaseExporter
class PytestBDDExporter(BaseExporter):
"""Exporter for pytest-bdd (Python)."""
def __init__(self) -> None:
"""Initialize the pytest-bdd exporter."""
pass
def export(self, features: List[str]) -> str:
"""Export features to pytest-bdd format.
Args:
features: List of Gherkin feature strings.
Returns:
pytest-bdd-compatible feature file content.
"""
combined = "\n\n".join(features)
return combined
def get_step_definitions_template(self) -> str:
"""Get pytest-bdd step definitions template.
Returns:
Step definitions template string.
"""
return '''"""pytest-bdd step definitions."""
import pytest
from pytest_bdd import given, when, then, scenarios
scenarios('features')
@given("a setup condition")
def setup_condition():
"""Given step implementation."""
return {}
@when("an action occurs")
def action_occurs():
"""When step implementation."""
pass
@then("an expected result")
def expected_result():
"""Then step implementation."""
pass
'''
def get_configuration_template(self) -> Dict[str, str]:
"""Get pytest-bdd configuration files.
Returns:
Dictionary mapping filenames to content.
"""
return {
"conftest.py": '''"""pytest configuration and fixtures."""
import pytest
from pytest_bdd import scenarios
scenarios('features')
@pytest.fixture
def context():
"""Shared test context."""
return {}
def pytest_configure(config):
"""Configure pytest."""
pass
''',
"pytest.ini": '''[pytest]
bdd_features_base_dir = features/
''',
}
def generate_step_definitions(self, scenarios: List[str], feature_name: str = "features") -> str:
"""Generate step definitions for given scenarios.
Args:
scenarios: List of scenario texts.
feature_name: Name of the feature file.
Returns:
Step definitions Python code.
"""
step_defs = []
for scenario in scenarios:
lines = scenario.split("\n")
scenario_name = ""
for line in lines:
stripped = line.strip()
if stripped.startswith("Scenario:"):
scenario_name = stripped[9:].strip().replace(" ", "_")
break
for line in lines:
stripped = line.strip()
if stripped.startswith(("Given ", "When ", "Then ", "And ")):
step_text = " ".join(stripped.split()[1:])
step_def = stripped.split()[0].lower()
params = self._extract_parameters(step_text)
param_str = ", ".join(f'"{p}"' for p in params) if params else ""
if params:
step_impl = f'''@pytest.{step_def}("{step_text}")
def {step_def}_{scenario_name}({", ".join(params)}):
"""{stripped.split()[0]} step implementation."""
pass
'''
else:
step_impl = f'''@{step_def}("{step_text}")
def {step_def}_{scenario_name}():
"""{stripped.split()[0]} step implementation."""
pass
'''
step_defs.append(step_impl)
return "\n".join(step_defs)
def _extract_parameters(self, step_text: str) -> List[str]:
"""Extract parameters from a step text."""
import re
return re.findall(r"<([^>]+)>", step_text)