Merge branch 'master' into anonymous-step-funcs

This commit is contained in:
Alessio Bogon 2022-07-15 18:24:56 +02:00 committed by GitHub
commit 5854666686
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 49 deletions

View File

@ -3,7 +3,7 @@
repos:
- repo: https://github.com/psf/black
# If you update the version here, also update it in tox.ini (py*-pytestlatest-linters)
rev: 22.3.0
rev: 22.6.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
@ -12,14 +12,14 @@ repos:
- id: isort
name: isort (python)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/asottile/pyupgrade
rev: v2.32.1
rev: v2.37.1
hooks:
- id: pyupgrade
args: ["--py37-plus"]

5
poetry.lock generated
View File

@ -1,6 +1,6 @@
[[package]]
name = "atomicwrites"
version = "1.4.0"
version = "1.4.1"
description = "Atomic file writes."
category = "main"
optional = false
@ -386,8 +386,7 @@ content-hash = "a7818e3872ac60220902d85673d411ecfd067f8ec89a6099e4f720c5925e535a
[metadata.files]
atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
{file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
]
attrs = [
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},

View File

@ -12,17 +12,16 @@ test_publish_article = scenario(
"""
from __future__ import annotations
import collections
import os
import re
from typing import TYPE_CHECKING, Callable, cast
import pytest
from _pytest.fixtures import FixtureLookupError, FixtureManager, FixtureRequest, call_fixture_func
from _pytest.fixtures import FixtureManager, FixtureRequest, call_fixture_func
from . import exceptions
from .feature import get_feature, get_features
from .steps import StepFunctionContext, get_step_fixture_name, inject_fixture
from .steps import StepFunctionContext, inject_fixture
from .utils import CONFIG_STACK, get_args, get_caller_module_locals, get_caller_module_path
if TYPE_CHECKING:
@ -45,27 +44,17 @@ def find_argumented_step_function(name: str, type_: str, fixturemanager: Fixture
if step_func_context is None:
continue
if step_func_context.type != type_:
continue
match = step_func_context.parser.is_matching(name)
if not match:
continue
if step_func_context.type != type_:
continue
return step_func_context
return None
def _find_step_function(request: FixtureRequest, step: Step, scenario: Scenario) -> StepFunctionContext:
"""Match the step defined by the parser."""
# Could not find a fixture with the same name, let's see if there is a parser involved
step_func_context = find_argumented_step_function(step.name, step.type, request._fixturemanager)
if step_func_context is None:
raise exceptions.StepDefinitionNotFoundError(
f"Step definition is not found: {step}. "
f'Line {step.line_number} in scenario "{scenario.name}" in the feature "{scenario.feature.filename}"'
)
return step_func_context
def _execute_step_function(
request: FixtureRequest, scenario: Scenario, step: Step, context: StepFunctionContext
) -> None:
@ -80,33 +69,33 @@ def _execute_step_function(
}
request.config.hook.pytest_bdd_before_step(**kw)
try: # TODO: Move this to the places where an exception can actually be raised
# Get the step argument values.
converters = context.converters
kwargs = {}
if context.parser:
for arg, value in context.parser.parse_arguments(step.name).items():
if arg in converters:
value = converters[arg](value)
kwargs[arg] = value
# Get the step argument values.
converters = context.converters
kwargs = {}
args = get_args(context.step_func)
try:
for arg, value in context.parser.parse_arguments(step.name).items():
if arg in converters:
value = converters[arg](value)
kwargs[arg] = value
args = get_args(context.step_func)
kwargs = {arg: kwargs[arg] if arg in kwargs else request.getfixturevalue(arg) for arg in args}
kw["step_func_args"] = kwargs
request.config.hook.pytest_bdd_before_step_call(**kw)
# Execute the step as if it was a pytest fixture, so that we can allow "yield" statements in it
return_value = call_fixture_func(fixturefunc=context.step_func, request=request, kwargs=kwargs)
if context.target_fixture is not None:
inject_fixture(request, context.target_fixture, return_value)
request.config.hook.pytest_bdd_after_step(**kw)
except Exception as exception:
request.config.hook.pytest_bdd_step_error(exception=exception, **kw)
raise
if context.target_fixture is not None:
inject_fixture(request, context.target_fixture, return_value)
request.config.hook.pytest_bdd_after_step(**kw)
def _execute_scenario(feature: Feature, scenario: Scenario, request: FixtureRequest) -> None:
"""Execute the scenario.
@ -119,13 +108,17 @@ def _execute_scenario(feature: Feature, scenario: Scenario, request: FixtureRequ
request.config.hook.pytest_bdd_before_scenario(request=request, feature=feature, scenario=scenario)
for step in scenario.steps:
try:
step_func_context = _find_step_function(request, step, scenario)
except exceptions.StepDefinitionNotFoundError as exception:
request.config.hook.pytest_bdd_step_func_lookup_error(
request=request, feature=feature, scenario=scenario, step=step, exception=exception
context = find_argumented_step_function(step.name, step.type, request._fixturemanager)
if context is None:
exc = exceptions.StepDefinitionNotFoundError(
f"Step definition is not found: {step}. "
f'Line {step.line_number} in scenario "{scenario.name}" in the feature "{scenario.feature.filename}"'
)
raise
request.config.hook.pytest_bdd_step_func_lookup_error(
request=request, feature=feature, scenario=scenario, step=step, exception=exc
)
raise exc
step_func_context = context
try:
_execute_step_function(request, scenario, step, step_func_context)

View File

@ -192,9 +192,6 @@ def inject_fixture(request: FixtureRequest, arg: str, value: Any) -> None:
request.addfinalizer(fin)
# inject fixture definition
# TODO: This seems wrong, since pytest treats the last elements as the highest priority ones
# request._fixturemanager._arg2fixturedefs.setdefault(arg, []).insert(0, fd)
# This seems more correct:
request._fixturemanager._arg2fixturedefs.setdefault(arg, []).append(fd)
# inject fixture value in request cache

View File

@ -14,5 +14,3 @@ THEN = "then"
TAG = "tag"
STEP_TYPES = (GIVEN, WHEN, THEN)
# TODO: Make an enum for StepType