Use "from __future__ import annotations" to be less verbose
This commit is contained in:
parent
4fd1ab950c
commit
021aa3a2e3
|
@ -22,4 +22,4 @@ repos:
|
||||||
rev: v2.31.0
|
rev: v2.31.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py37-plus]
|
args: ["--py37-plus", "--keep-runtime-typing"]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""pytest-bdd public API."""
|
"""pytest-bdd public API."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from pytest_bdd.scenario import scenario, scenarios
|
from pytest_bdd.scenario import scenario, scenarios
|
||||||
from pytest_bdd.steps import given, then, when
|
from pytest_bdd.steps import given, then, when
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Cucumber json output formatter."""
|
"""Cucumber json output formatter."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import math
|
import math
|
||||||
|
@ -13,7 +14,7 @@ if TYPE_CHECKING:
|
||||||
from _pytest.terminal import TerminalReporter
|
from _pytest.terminal import TerminalReporter
|
||||||
|
|
||||||
|
|
||||||
def add_options(parser: "Parser") -> None:
|
def add_options(parser: Parser) -> None:
|
||||||
"""Add pytest-bdd options."""
|
"""Add pytest-bdd options."""
|
||||||
group = parser.getgroup("bdd", "Cucumber JSON")
|
group = parser.getgroup("bdd", "Cucumber JSON")
|
||||||
group.addoption(
|
group.addoption(
|
||||||
|
@ -27,7 +28,7 @@ def add_options(parser: "Parser") -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def configure(config: "Config") -> None:
|
def configure(config: Config) -> None:
|
||||||
cucumber_json_path = config.option.cucumber_json_path
|
cucumber_json_path = config.option.cucumber_json_path
|
||||||
# prevent opening json log on worker nodes (xdist)
|
# prevent opening json log on worker nodes (xdist)
|
||||||
if cucumber_json_path and not hasattr(config, "workerinput"):
|
if cucumber_json_path and not hasattr(config, "workerinput"):
|
||||||
|
@ -35,7 +36,7 @@ def configure(config: "Config") -> None:
|
||||||
config.pluginmanager.register(config._bddcucumberjson)
|
config.pluginmanager.register(config._bddcucumberjson)
|
||||||
|
|
||||||
|
|
||||||
def unconfigure(config: "Config") -> None:
|
def unconfigure(config: Config) -> None:
|
||||||
xml = getattr(config, "_bddcucumberjson", None)
|
xml = getattr(config, "_bddcucumberjson", None)
|
||||||
if xml is not None:
|
if xml is not None:
|
||||||
del config._bddcucumberjson
|
del config._bddcucumberjson
|
||||||
|
@ -55,7 +56,7 @@ class LogBDDCucumberJSON:
|
||||||
def append(self, obj):
|
def append(self, obj):
|
||||||
self.features[-1].append(obj)
|
self.features[-1].append(obj)
|
||||||
|
|
||||||
def _get_result(self, step: Dict[str, Any], report: "TestReport", error_message: bool = False) -> Dict[str, Any]:
|
def _get_result(self, step: Dict[str, Any], report: TestReport, error_message: bool = False) -> Dict[str, Any]:
|
||||||
"""Get scenario test run result.
|
"""Get scenario test run result.
|
||||||
|
|
||||||
:param step: `Step` step we get result for
|
:param step: `Step` step we get result for
|
||||||
|
@ -86,7 +87,7 @@ class LogBDDCucumberJSON:
|
||||||
"""
|
"""
|
||||||
return [{"name": tag, "line": item["line_number"] - 1} for tag in item["tags"]]
|
return [{"name": tag, "line": item["line_number"] - 1} for tag in item["tags"]]
|
||||||
|
|
||||||
def pytest_runtest_logreport(self, report: "TestReport") -> None:
|
def pytest_runtest_logreport(self, report: TestReport) -> None:
|
||||||
try:
|
try:
|
||||||
scenario = report.scenario
|
scenario = report.scenario
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -145,5 +146,5 @@ class LogBDDCucumberJSON:
|
||||||
with open(self.logfile, "w", encoding="utf-8") as logfile:
|
with open(self.logfile, "w", encoding="utf-8") as logfile:
|
||||||
logfile.write(json.dumps(list(self.features.values())))
|
logfile.write(json.dumps(list(self.features.values())))
|
||||||
|
|
||||||
def pytest_terminal_summary(self, terminalreporter: "TerminalReporter") -> None:
|
def pytest_terminal_summary(self, terminalreporter: TerminalReporter) -> None:
|
||||||
terminalreporter.write_sep("-", f"generated json file: {self.logfile}")
|
terminalreporter.write_sep("-", f"generated json file: {self.logfile}")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""pytest-bdd Exceptions."""
|
"""pytest-bdd Exceptions."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
class ScenarioIsDecoratorOnly(Exception):
|
class ScenarioIsDecoratorOnly(Exception):
|
||||||
|
|
|
@ -23,6 +23,8 @@ Syntax example:
|
||||||
:note: There are no multiline steps, the description of the step must fit in
|
:note: There are no multiline steps, the description of the step must fit in
|
||||||
one line.
|
one line.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""pytest-bdd missing test code generation."""
|
"""pytest-bdd missing test code generation."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -50,7 +51,7 @@ def cmdline_main(config: Config) -> Optional[int]:
|
||||||
return show_missing_code(config)
|
return show_missing_code(config)
|
||||||
|
|
||||||
|
|
||||||
def generate_code(features: "List[Feature]", scenarios: "List[ScenarioTemplate]", steps: "List[Step]") -> str:
|
def generate_code(features: List[Feature], scenarios: List[ScenarioTemplate], steps: List[Step]) -> str:
|
||||||
"""Generate test code for the given filenames."""
|
"""Generate test code for the given filenames."""
|
||||||
grouped_steps = group_steps(steps)
|
grouped_steps = group_steps(steps)
|
||||||
template = template_lookup.get_template("test.py.mak")
|
template = template_lookup.get_template("test.py.mak")
|
||||||
|
@ -71,7 +72,7 @@ def show_missing_code(config: Config) -> int:
|
||||||
return wrap_session(config, _show_missing_code_main)
|
return wrap_session(config, _show_missing_code_main)
|
||||||
|
|
||||||
|
|
||||||
def print_missing_code(scenarios: "List[ScenarioTemplate]", steps: "List[Step]") -> None:
|
def print_missing_code(scenarios: List[ScenarioTemplate], steps: List[Step]) -> None:
|
||||||
"""Print missing code with TerminalWriter."""
|
"""Print missing code with TerminalWriter."""
|
||||||
tw = py.io.TerminalWriter()
|
tw = py.io.TerminalWriter()
|
||||||
scenario = step = None
|
scenario = step = None
|
||||||
|
@ -138,7 +139,7 @@ def _find_step_fixturedef(
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def parse_feature_files(paths: List[str], **kwargs: Any) -> "Tuple[List[Feature], List[ScenarioTemplate], List[Step]]":
|
def parse_feature_files(paths: List[str], **kwargs: Any) -> Tuple[List[Feature], List[ScenarioTemplate], List[Step]]:
|
||||||
"""Parse feature files of given paths.
|
"""Parse feature files of given paths.
|
||||||
|
|
||||||
:param paths: `list` of paths (file or dirs)
|
:param paths: `list` of paths (file or dirs)
|
||||||
|
@ -157,7 +158,7 @@ def parse_feature_files(paths: List[str], **kwargs: Any) -> "Tuple[List[Feature]
|
||||||
return features, scenarios, steps
|
return features, scenarios, steps
|
||||||
|
|
||||||
|
|
||||||
def group_steps(steps: "List[Step]") -> "List[Step]":
|
def group_steps(steps: List[Step]) -> List[Step]:
|
||||||
"""Group steps by type."""
|
"""Group steps by type."""
|
||||||
steps = sorted(steps, key=lambda step: step.type)
|
steps = sorted(steps, key=lambda step: step.type)
|
||||||
seen_steps = set()
|
seen_steps = set()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
"""Pytest-bdd pytest hooks."""
|
"""Pytest-bdd pytest hooks."""
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
|
@ -75,7 +77,7 @@ def get_step_type(line: str) -> Optional[str]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> "Feature":
|
def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> Feature:
|
||||||
"""Parse the feature file.
|
"""Parse the feature file.
|
||||||
|
|
||||||
:param str basedir: Feature files base directory.
|
:param str basedir: Feature files base directory.
|
||||||
|
@ -186,7 +188,7 @@ class Feature:
|
||||||
rel_filename: str,
|
rel_filename: str,
|
||||||
name: Optional[str],
|
name: Optional[str],
|
||||||
tags: Set,
|
tags: Set,
|
||||||
background: "Optional[Background]",
|
background: Optional[Background],
|
||||||
line_number: int,
|
line_number: int,
|
||||||
description: str,
|
description: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -197,7 +199,7 @@ class Feature:
|
||||||
self.name: Optional[str] = name
|
self.name: Optional[str] = name
|
||||||
self.line_number: int = line_number
|
self.line_number: int = line_number
|
||||||
self.description: str = description
|
self.description: str = description
|
||||||
self.background: "Optional[Background]" = background
|
self.background: Optional[Background] = background
|
||||||
|
|
||||||
|
|
||||||
class ScenarioTemplate:
|
class ScenarioTemplate:
|
||||||
|
@ -205,7 +207,7 @@ class ScenarioTemplate:
|
||||||
|
|
||||||
Created when parsing the feature file, it will then be combined with the examples to create a Scenario."""
|
Created when parsing the feature file, it will then be combined with the examples to create a Scenario."""
|
||||||
|
|
||||||
def __init__(self, feature: "Feature", name: str, line_number: int, tags=None):
|
def __init__(self, feature: Feature, name: str, line_number: int, tags=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param str name: Scenario name.
|
:param str name: Scenario name.
|
||||||
|
@ -214,12 +216,12 @@ class ScenarioTemplate:
|
||||||
"""
|
"""
|
||||||
self.feature = feature
|
self.feature = feature
|
||||||
self.name = name
|
self.name = name
|
||||||
self._steps: "typing.List[Step]" = []
|
self._steps: typing.List[Step] = []
|
||||||
self.examples = Examples()
|
self.examples = Examples()
|
||||||
self.line_number = line_number
|
self.line_number = line_number
|
||||||
self.tags = tags or set()
|
self.tags = tags or set()
|
||||||
|
|
||||||
def add_step(self, step: "Step") -> None:
|
def add_step(self, step: Step) -> None:
|
||||||
"""Add step to the scenario.
|
"""Add step to the scenario.
|
||||||
|
|
||||||
:param pytest_bdd.parser.Step step: Step.
|
:param pytest_bdd.parser.Step step: Step.
|
||||||
|
@ -228,11 +230,11 @@ class ScenarioTemplate:
|
||||||
self._steps.append(step)
|
self._steps.append(step)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def steps(self) -> "List[Step]":
|
def steps(self) -> List[Step]:
|
||||||
background = self.feature.background
|
background = self.feature.background
|
||||||
return (background.steps if background else []) + self._steps
|
return (background.steps if background else []) + self._steps
|
||||||
|
|
||||||
def render(self, context: typing.Mapping[str, typing.Any]) -> "Scenario":
|
def render(self, context: typing.Mapping[str, typing.Any]) -> Scenario:
|
||||||
steps = [
|
steps = [
|
||||||
Step(
|
Step(
|
||||||
name=templated_step.render(context),
|
name=templated_step.render(context),
|
||||||
|
@ -250,7 +252,7 @@ class Scenario:
|
||||||
|
|
||||||
"""Scenario."""
|
"""Scenario."""
|
||||||
|
|
||||||
def __init__(self, feature: "Feature", name: str, line_number: int, steps: "typing.List[Step]", tags=None):
|
def __init__(self, feature: Feature, name: str, line_number: int, steps: typing.List[Step], tags=None):
|
||||||
"""Scenario constructor.
|
"""Scenario constructor.
|
||||||
|
|
||||||
:param pytest_bdd.parser.Feature feature: Feature.
|
:param pytest_bdd.parser.Feature feature: Feature.
|
||||||
|
@ -288,8 +290,8 @@ class Step:
|
||||||
self.failed: bool = False
|
self.failed: bool = False
|
||||||
self.start: int = 0 # TODO: Unused
|
self.start: int = 0 # TODO: Unused
|
||||||
self.stop: int = 0 # TODO: Unused
|
self.stop: int = 0 # TODO: Unused
|
||||||
self.scenario: "Optional[ScenarioTemplate]" = None
|
self.scenario: Optional[ScenarioTemplate] = None
|
||||||
self.background: "Optional[Background]" = None
|
self.background: Optional[Background] = None
|
||||||
|
|
||||||
def add_line(self, line: str) -> None:
|
def add_line(self, line: str) -> None:
|
||||||
"""Add line to the multiple step.
|
"""Add line to the multiple step.
|
||||||
|
@ -340,17 +342,17 @@ class Background:
|
||||||
|
|
||||||
"""Background."""
|
"""Background."""
|
||||||
|
|
||||||
def __init__(self, feature: "Feature", line_number: int) -> None:
|
def __init__(self, feature: Feature, line_number: int) -> None:
|
||||||
"""Background constructor.
|
"""Background constructor.
|
||||||
|
|
||||||
:param pytest_bdd.parser.Feature feature: Feature.
|
:param pytest_bdd.parser.Feature feature: Feature.
|
||||||
:param int line_number: Line number.
|
:param int line_number: Line number.
|
||||||
"""
|
"""
|
||||||
self.feature: "Feature" = feature
|
self.feature: Feature = feature
|
||||||
self.line_number: int = line_number
|
self.line_number: int = line_number
|
||||||
self.steps: "typing.List[Step]" = []
|
self.steps: typing.List[Step] = []
|
||||||
|
|
||||||
def add_step(self, step: "Step") -> None:
|
def add_step(self, step: Step) -> None:
|
||||||
"""Add step to the background."""
|
"""Add step to the background."""
|
||||||
step.background = self
|
step.background = self
|
||||||
self.steps.append(step)
|
self.steps.append(step)
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
"""Step parsers."""
|
"""Step parsers."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import re as base_re
|
import re as base_re
|
||||||
from functools import partial
|
|
||||||
from typing import Any, Dict, cast
|
from typing import Any, Dict, cast
|
||||||
|
|
||||||
import parse as base_parse
|
import parse as base_parse
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Pytest plugin entry point. Used for any fixtures needed."""
|
"""Pytest plugin entry point. Used for any fixtures needed."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, Optional
|
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, Optional
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ if TYPE_CHECKING:
|
||||||
from .parser import Feature, Scenario, Step
|
from .parser import Feature, Scenario, Step
|
||||||
|
|
||||||
|
|
||||||
def pytest_addhooks(pluginmanager: "PytestPluginManager") -> None:
|
def pytest_addhooks(pluginmanager: PytestPluginManager) -> None:
|
||||||
"""Register plugin hooks."""
|
"""Register plugin hooks."""
|
||||||
from pytest_bdd import hooks
|
from pytest_bdd import hooks
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ def _pytest_bdd_example() -> Dict:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser: "Parser") -> None:
|
def pytest_addoption(parser: Parser) -> None:
|
||||||
"""Add pytest-bdd options."""
|
"""Add pytest-bdd options."""
|
||||||
add_bdd_ini(parser)
|
add_bdd_ini(parser)
|
||||||
cucumber_json.add_options(parser)
|
cucumber_json.add_options(parser)
|
||||||
|
@ -54,42 +55,42 @@ def pytest_addoption(parser: "Parser") -> None:
|
||||||
gherkin_terminal_reporter.add_options(parser)
|
gherkin_terminal_reporter.add_options(parser)
|
||||||
|
|
||||||
|
|
||||||
def add_bdd_ini(parser: "Parser") -> None:
|
def add_bdd_ini(parser: Parser) -> None:
|
||||||
parser.addini("bdd_features_base_dir", "Base features directory.")
|
parser.addini("bdd_features_base_dir", "Base features directory.")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.trylast
|
@pytest.mark.trylast
|
||||||
def pytest_configure(config: "Config") -> None:
|
def pytest_configure(config: Config) -> None:
|
||||||
"""Configure all subplugins."""
|
"""Configure all subplugins."""
|
||||||
CONFIG_STACK.append(config)
|
CONFIG_STACK.append(config)
|
||||||
cucumber_json.configure(config)
|
cucumber_json.configure(config)
|
||||||
gherkin_terminal_reporter.configure(config)
|
gherkin_terminal_reporter.configure(config)
|
||||||
|
|
||||||
|
|
||||||
def pytest_unconfigure(config: "Config") -> None:
|
def pytest_unconfigure(config: Config) -> None:
|
||||||
"""Unconfigure all subplugins."""
|
"""Unconfigure all subplugins."""
|
||||||
CONFIG_STACK.pop()
|
CONFIG_STACK.pop()
|
||||||
cucumber_json.unconfigure(config)
|
cucumber_json.unconfigure(config)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.hookwrapper
|
@pytest.mark.hookwrapper
|
||||||
def pytest_runtest_makereport(item: "Item", call: "CallInfo") -> Iterator:
|
def pytest_runtest_makereport(item: Item, call: CallInfo) -> Iterator:
|
||||||
outcome = yield
|
outcome = yield
|
||||||
reporting.runtest_makereport(item, call, outcome.get_result())
|
reporting.runtest_makereport(item, call, outcome.get_result())
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.tryfirst
|
@pytest.mark.tryfirst
|
||||||
def pytest_bdd_before_scenario(request: "FixtureRequest", feature: "Feature", scenario: "Scenario") -> None:
|
def pytest_bdd_before_scenario(request: FixtureRequest, feature: Feature, scenario: Scenario) -> None:
|
||||||
reporting.before_scenario(request, feature, scenario)
|
reporting.before_scenario(request, feature, scenario)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.tryfirst
|
@pytest.mark.tryfirst
|
||||||
def pytest_bdd_step_error(
|
def pytest_bdd_step_error(
|
||||||
request: "FixtureRequest",
|
request: FixtureRequest,
|
||||||
feature: "Feature",
|
feature: Feature,
|
||||||
scenario: "Scenario",
|
scenario: Scenario,
|
||||||
step: "Step",
|
step: Step,
|
||||||
step_func: "Callable",
|
step_func: Callable,
|
||||||
step_func_args: Dict,
|
step_func_args: Dict,
|
||||||
exception: Exception,
|
exception: Exception,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -98,27 +99,27 @@ def pytest_bdd_step_error(
|
||||||
|
|
||||||
@pytest.mark.tryfirst
|
@pytest.mark.tryfirst
|
||||||
def pytest_bdd_before_step(
|
def pytest_bdd_before_step(
|
||||||
request: "FixtureRequest", feature: "Feature", scenario: "Scenario", step: "Step", step_func: "Callable"
|
request: FixtureRequest, feature: Feature, scenario: Scenario, step: Step, step_func: Callable
|
||||||
) -> None:
|
) -> None:
|
||||||
reporting.before_step(request, feature, scenario, step, step_func)
|
reporting.before_step(request, feature, scenario, step, step_func)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.tryfirst
|
@pytest.mark.tryfirst
|
||||||
def pytest_bdd_after_step(
|
def pytest_bdd_after_step(
|
||||||
request: "FixtureRequest",
|
request: FixtureRequest,
|
||||||
feature: "Feature",
|
feature: Feature,
|
||||||
scenario: "Scenario",
|
scenario: Scenario,
|
||||||
step: "Step",
|
step: Step,
|
||||||
step_func: "Callable",
|
step_func: Callable,
|
||||||
step_func_args: Dict[str, Any],
|
step_func_args: Dict[str, Any],
|
||||||
) -> None:
|
) -> None:
|
||||||
reporting.after_step(request, feature, scenario, step, step_func, step_func_args)
|
reporting.after_step(request, feature, scenario, step, step_func, step_func_args)
|
||||||
|
|
||||||
|
|
||||||
def pytest_cmdline_main(config: "Config") -> Optional[int]:
|
def pytest_cmdline_main(config: Config) -> Optional[int]:
|
||||||
return generation.cmdline_main(config)
|
return generation.cmdline_main(config)
|
||||||
|
|
||||||
|
|
||||||
def pytest_bdd_apply_tag(tag: str, function: "Callable") -> "Callable":
|
def pytest_bdd_apply_tag(tag: str, function: Callable) -> Callable:
|
||||||
mark = getattr(pytest.mark, tag)
|
mark = getattr(pytest.mark, tag)
|
||||||
return mark(function)
|
return mark(function)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
Collection of the scenario execution statuses, timing and other information
|
Collection of the scenario execution statuses, timing and other information
|
||||||
that enriches the pytest test reporting.
|
that enriches the pytest test reporting.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from typing import TYPE_CHECKING, Any, Callable, Dict
|
from typing import TYPE_CHECKING, Any, Callable, Dict
|
||||||
|
@ -22,7 +23,7 @@ class StepReport:
|
||||||
failed = False
|
failed = False
|
||||||
stopped = None
|
stopped = None
|
||||||
|
|
||||||
def __init__(self, step: "Step") -> None:
|
def __init__(self, step: Step) -> None:
|
||||||
"""Step report constructor.
|
"""Step report constructor.
|
||||||
|
|
||||||
:param pytest_bdd.parser.Step step: Step.
|
:param pytest_bdd.parser.Step step: Step.
|
||||||
|
@ -70,7 +71,7 @@ class ScenarioReport:
|
||||||
"""Scenario execution report."""
|
"""Scenario execution report."""
|
||||||
|
|
||||||
# TODO: Remove unused argument "node"
|
# TODO: Remove unused argument "node"
|
||||||
def __init__(self, scenario: "Scenario", node: Any) -> None:
|
def __init__(self, scenario: Scenario, node: Any) -> None:
|
||||||
"""Scenario report constructor.
|
"""Scenario report constructor.
|
||||||
|
|
||||||
:param pytest_bdd.parser.Scenario scenario: Scenario.
|
:param pytest_bdd.parser.Scenario scenario: Scenario.
|
||||||
|
@ -80,7 +81,7 @@ class ScenarioReport:
|
||||||
self.step_reports = []
|
self.step_reports = []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_step_report(self) -> "StepReport":
|
def current_step_report(self) -> StepReport:
|
||||||
"""Get current step report.
|
"""Get current step report.
|
||||||
|
|
||||||
:return: Last or current step report.
|
:return: Last or current step report.
|
||||||
|
@ -88,7 +89,7 @@ class ScenarioReport:
|
||||||
"""
|
"""
|
||||||
return self.step_reports[-1]
|
return self.step_reports[-1]
|
||||||
|
|
||||||
def add_step_report(self, step_report: "StepReport") -> None:
|
def add_step_report(self, step_report: StepReport) -> None:
|
||||||
"""Add new step report.
|
"""Add new step report.
|
||||||
|
|
||||||
:param step_report: New current step report.
|
:param step_report: New current step report.
|
||||||
|
@ -132,7 +133,7 @@ class ScenarioReport:
|
||||||
self.add_step_report(report)
|
self.add_step_report(report)
|
||||||
|
|
||||||
|
|
||||||
def runtest_makereport(item: "Item", call: "CallInfo", rep: "TestReport") -> None:
|
def runtest_makereport(item: Item, call: CallInfo, rep: TestReport) -> None:
|
||||||
"""Store item in the report object."""
|
"""Store item in the report object."""
|
||||||
try:
|
try:
|
||||||
scenario_report = item.__scenario_report__
|
scenario_report = item.__scenario_report__
|
||||||
|
@ -143,17 +144,17 @@ def runtest_makereport(item: "Item", call: "CallInfo", rep: "TestReport") -> Non
|
||||||
rep.item = {"name": item.name}
|
rep.item = {"name": item.name}
|
||||||
|
|
||||||
|
|
||||||
def before_scenario(request: "FixtureRequest", feature: "Feature", scenario: "Scenario") -> None:
|
def before_scenario(request: FixtureRequest, feature: Feature, scenario: Scenario) -> None:
|
||||||
"""Create scenario report for the item."""
|
"""Create scenario report for the item."""
|
||||||
request.node.__scenario_report__ = ScenarioReport(scenario=scenario, node=request.node)
|
request.node.__scenario_report__ = ScenarioReport(scenario=scenario, node=request.node)
|
||||||
|
|
||||||
|
|
||||||
def step_error(
|
def step_error(
|
||||||
request: "FixtureRequest",
|
request: FixtureRequest,
|
||||||
feature: "Feature",
|
feature: Feature,
|
||||||
scenario: "Scenario",
|
scenario: Scenario,
|
||||||
step: "Step",
|
step: Step,
|
||||||
step_func: "Callable",
|
step_func: Callable,
|
||||||
step_func_args: Dict,
|
step_func_args: Dict,
|
||||||
exception: Exception,
|
exception: Exception,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -161,19 +162,17 @@ def step_error(
|
||||||
request.node.__scenario_report__.fail()
|
request.node.__scenario_report__.fail()
|
||||||
|
|
||||||
|
|
||||||
def before_step(
|
def before_step(request: FixtureRequest, feature: Feature, scenario: Scenario, step: Step, step_func: Callable) -> None:
|
||||||
request: "FixtureRequest", feature: "Feature", scenario: "Scenario", step: "Step", step_func: "Callable"
|
|
||||||
) -> None:
|
|
||||||
"""Store step start time."""
|
"""Store step start time."""
|
||||||
request.node.__scenario_report__.add_step_report(StepReport(step=step))
|
request.node.__scenario_report__.add_step_report(StepReport(step=step))
|
||||||
|
|
||||||
|
|
||||||
def after_step(
|
def after_step(
|
||||||
request: "FixtureRequest",
|
request: FixtureRequest,
|
||||||
feature: "Feature",
|
feature: Feature,
|
||||||
scenario: "Scenario",
|
scenario: Scenario,
|
||||||
step: "Step",
|
step: Step,
|
||||||
step_func: "Callable",
|
step_func: Callable,
|
||||||
step_func_args: Dict,
|
step_func_args: Dict,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Finalize the step report as successful."""
|
"""Finalize the step report as successful."""
|
||||||
|
|
|
@ -10,6 +10,8 @@ test_publish_article = scenario(
|
||||||
scenario_name="Publishing the article",
|
scenario_name="Publishing the article",
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -57,7 +59,7 @@ def find_argumented_step_fixture_name(
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _find_step_function(request: FixtureRequest, step: "Step", scenario: "Scenario") -> Any:
|
def _find_step_function(request: FixtureRequest, step: Step, scenario: Scenario) -> Any:
|
||||||
"""Match the step defined by the regular expression pattern.
|
"""Match the step defined by the regular expression pattern.
|
||||||
|
|
||||||
:param request: PyTest request object.
|
:param request: PyTest request object.
|
||||||
|
@ -85,7 +87,7 @@ def _find_step_function(request: FixtureRequest, step: "Step", scenario: "Scenar
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _execute_step_function(request: FixtureRequest, scenario: "Scenario", step: "Step", step_func: Callable) -> None:
|
def _execute_step_function(request: FixtureRequest, scenario: Scenario, step: Step, step_func: Callable) -> None:
|
||||||
"""Execute step function.
|
"""Execute step function.
|
||||||
|
|
||||||
:param request: PyTest request.
|
:param request: PyTest request.
|
||||||
|
@ -128,7 +130,7 @@ def _execute_step_function(request: FixtureRequest, scenario: "Scenario", step:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def _execute_scenario(feature: "Feature", scenario: "Scenario", request):
|
def _execute_scenario(feature: Feature, scenario: Scenario, request):
|
||||||
"""Execute the scenario.
|
"""Execute the scenario.
|
||||||
|
|
||||||
:param feature: Feature.
|
:param feature: Feature.
|
||||||
|
@ -157,7 +159,7 @@ FakeRequest = collections.namedtuple("FakeRequest", ["module"])
|
||||||
|
|
||||||
|
|
||||||
def _get_scenario_decorator(
|
def _get_scenario_decorator(
|
||||||
feature: "Feature", feature_name: str, templated_scenario: "ScenarioTemplate", scenario_name: str
|
feature: Feature, feature_name: str, templated_scenario: ScenarioTemplate, scenario_name: str
|
||||||
):
|
):
|
||||||
# HACK: Ideally we would use `def decorator(fn)`, but we want to return a custom exception
|
# HACK: Ideally we would use `def decorator(fn)`, but we want to return a custom exception
|
||||||
# when the decorator is misused.
|
# when the decorator is misused.
|
||||||
|
@ -202,8 +204,8 @@ def _get_scenario_decorator(
|
||||||
|
|
||||||
|
|
||||||
def collect_example_parametrizations(
|
def collect_example_parametrizations(
|
||||||
templated_scenario: "ScenarioTemplate",
|
templated_scenario: ScenarioTemplate,
|
||||||
) -> "typing.Optional[typing.List[ParameterSet]]":
|
) -> typing.Optional[typing.List[ParameterSet]]:
|
||||||
# We need to evaluate these iterators and store them as lists, otherwise
|
# We need to evaluate these iterators and store them as lists, otherwise
|
||||||
# we won't be able to do the cartesian product later (the second iterator will be consumed)
|
# we won't be able to do the cartesian product later (the second iterator will be consumed)
|
||||||
contexts = list(templated_scenario.examples.as_contexts())
|
contexts = list(templated_scenario.examples.as_contexts())
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""pytest-bdd scripts."""
|
"""pytest-bdd scripts."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -34,6 +34,7 @@ def given_beautiful_article(article):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Callable, Dict, Optional, Union
|
from typing import Any, Callable, Dict, Optional, Union
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Common type definitions."""
|
"""Common type definitions."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
FEATURE = "feature"
|
FEATURE = "feature"
|
||||||
SCENARIO_OUTLINE = "scenario outline"
|
SCENARIO_OUTLINE = "scenario outline"
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
"""Various utility functions."""
|
"""Various utility functions."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import pickle
|
import pickle
|
||||||
import re
|
import re
|
||||||
|
@ -11,7 +13,7 @@ if typing.TYPE_CHECKING:
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
from _pytest.pytester import RunResult
|
from _pytest.pytester import RunResult
|
||||||
|
|
||||||
CONFIG_STACK: "List[Config]" = []
|
CONFIG_STACK: List[Config] = []
|
||||||
|
|
||||||
|
|
||||||
def get_args(func: Callable) -> List[str]:
|
def get_args(func: Callable) -> List[str]:
|
||||||
|
@ -57,7 +59,7 @@ def dump_obj(*objects: Any) -> None:
|
||||||
print(f"{_DUMP_START}{encoded}{_DUMP_END}")
|
print(f"{_DUMP_START}{encoded}{_DUMP_END}")
|
||||||
|
|
||||||
|
|
||||||
def collect_dumped_objects(result: "RunResult"):
|
def collect_dumped_objects(result: RunResult):
|
||||||
"""Parse all the objects dumped with `dump_object` from the result.
|
"""Parse all the objects dumped with `dump_object` from the result.
|
||||||
|
|
||||||
Note: You must run the result with output to stdout enabled.
|
Note: You must run the result with output to stdout enabled.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, Optional
|
from typing import TYPE_CHECKING, Any, Optional
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -13,7 +15,7 @@ PYTEST_6 = PYTEST_VERSION >= Version("6")
|
||||||
if PYTEST_6:
|
if PYTEST_6:
|
||||||
|
|
||||||
def assert_outcomes(
|
def assert_outcomes(
|
||||||
result: "RunResult",
|
result: RunResult,
|
||||||
passed: int = 0,
|
passed: int = 0,
|
||||||
skipped: int = 0,
|
skipped: int = 0,
|
||||||
failed: int = 0,
|
failed: int = 0,
|
||||||
|
@ -29,7 +31,7 @@ if PYTEST_6:
|
||||||
else:
|
else:
|
||||||
|
|
||||||
def assert_outcomes(
|
def assert_outcomes(
|
||||||
result: "RunResult",
|
result: RunResult,
|
||||||
passed=0,
|
passed=0,
|
||||||
skipped=0,
|
skipped=0,
|
||||||
failed=0,
|
failed=0,
|
||||||
|
|
Loading…
Reference in New Issue