135 lines
3.5 KiB
Python
135 lines
3.5 KiB
Python
"""pytest-bdd exporter for pytest projects."""
|
|
|
|
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)
|
|
", ".join(f'"{p}"' for p in params) if params else ""
|
|
|
|
if params:
|
|
step_impl = f'@pytest.{step_def}("{step_text}")\ndef {step_def}_{scenario_name}({', '.join(params)}):\n """{stripped.split()[0]} step implementation."""\n pass\n'
|
|
else:
|
|
step_impl = f'@{step_def}("{step_text}")\ndef {step_def}_{scenario_name}():\n """{stripped.split()[0]} step implementation."""\n pass\n'
|
|
|
|
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)
|