elchupanebrej / pytest-bdd-ng

BDD library for the py.test runner
https://pytest-bdd-ng.readthedocs.io/en/default/
Other
14 stars 3 forks source link

Support for multiline steps? #81

Closed aspenboy closed 1 year ago

aspenboy commented 2 years ago

Hi,

Does pytest-bdd-ng supports multiline steps? It is described in here: https://pytest-bdd-ng.readthedocs.io/en/stable/#multiline-steps but in my case I'm getting "step definition not found" error. My step looks like this:

Given user has some table params:
      | some parameter 1 | value 1   |
      | some parameter 2 | value 2   |

And the implementation:

@given(parsers.parse("user has some table params:\n{table_without_headers}"))
def step_impl(table_without_headers, test_environment):
    unit = parse_str_table(table_without_headers)

I've tried with both 1.2.2 and 1.2.3 version (1.2.3 has a bit problematic change when it comes to shared steps handling, so I'll have to stick to 1.2.2 for a while anyway).

chajath commented 2 years ago

I figured all the Gherkin parsed step information is available from the step parameter. To access the data table, you can do:

@given(parsers.parse("user has some table params:"))
def step_impl(step):
    data_table = step.data_table
elchupanebrej commented 2 years ago

Hi, multiline steps are supported only for the legacy parser, because they are not part of the standard. If matching by multiline steps is needed - it's better to use doc strings with custom matchers

In future versions, only the original parser would be supported to conform with the original gherkin tools. And a big part of the documentation will be rewritten. Thanks for the report!

elchupanebrej commented 2 years ago

I've tried with both 1.2.2 and 1.2.3 version (1.2.3 has a bit problematic change when it comes to shared steps handling, so I'll have to stick to 1.2.2 for a while anyway).

Could you please give me some more information about your use case please?

aspenboy commented 2 years ago

I've tried with both 1.2.2 and 1.2.3 version (1.2.3 has a bit problematic change when it comes to shared steps handling, so I'll have to stick to 1.2.2 for a while anyway).

Could you please give me some more information about your use case please?

Sure thing, apologies for delayed reply.

So with 1.2.2 I found very useful "workaround" for the problem of shared steps (the same step used in many scenarios). What I did was:

In 1.2.3 this is no longer an option. I tried to use feature autoloading using --feature-autoload flag, but I'm getting step definition not found error. In my implementation I pointed scenarios to a folder with feature files:

scenarios("../features")

but it doesn't help - I'm getting this error:

pw/lib/python3.10/site-packages/pytest_bdd/collector.py:17: in collect
    return super().collect()
pw/lib/python3.10/site-packages/_pytest/python.py:525: in collect
    return super().collect()
pw/lib/python3.10/site-packages/_pytest/python.py:446: in collect
    res = ihook.pytest_pycollect_makeitem(
pw/lib/python3.10/site-packages/pluggy/_hooks.py:265: in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
pw/lib/python3.10/site-packages/pluggy/_manager.py:80: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
pw/lib/python3.10/site-packages/_pytest/python.py:262: in pytest_pycollect_makeitem
    return list(collector._genfunctions(name, obj))
pw/lib/python3.10/site-packages/_pytest/python.py:489: in _genfunctions
    self.ihook.pytest_generate_tests.call_extra(methods, dict(metafunc=metafunc))
pw/lib/python3.10/site-packages/pluggy/_hooks.py:292: in call_extra
    return self(**kwargs)
pw/lib/python3.10/site-packages/pluggy/_hooks.py:265: in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
pw/lib/python3.10/site-packages/pluggy/_manager.py:80: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
pw/lib/python3.10/site-packages/pytest_bdd/plugin.py:112: in pytest_generate_tests
    metafunc.function.__pytest_bdd_scenario_registry__.parametrize(metafunc)
pw/lib/python3.10/site-packages/pytest_bdd/scenario.py:166: in parametrize
    (feature, scenario) for _, (func, feature, scenario) in self.resolved_locators.items() if func is test_func
pw/lib/python3.10/site-packages/pytest_bdd/scenario.py:157: in resolved_locators
    for feature, scenario in locator.resolve():
pw/lib/python3.10/site-packages/pytest_bdd/scenario.py:99: in resolve
    feature = self.parser.parse(
pw/lib/python3.10/site-packages/pytest_bdd/parser.py:113: in parse
    with path.open(mode="r", encoding=encoding) as feature_file:
/usr/lib/python3.10/pathlib.py:1119: in open
    return self._accessor.open(self, mode, buffering, encoding, errors,
E   IsADirectoryError: [Errno 21] Is a directory: '/home/**/tests/features'
elchupanebrej commented 2 years ago

import tests.step_defs.shared_steps as shared_steps

scenarios("../features/my_scenarios_with_some_shared_steps.feature") step.from_module(shared_steps)

Thanks for your reply, code above has to be changed with

from tests.step_defs.shared_steps import *

scenarios("../features/my_scenarios_with_some_shared_steps.feature")

The idea was to not use manual registration of steps, it was tricky to implement, but way was found)

Thanks for the clarification, please check the code above and give your feedback. This aspect will be updated in the next version of the documentation

elchupanebrej commented 1 year ago

Please investigate release 2.0.0;

Multiline steps are there; example of usage https://github.com/elchupanebrej/pytest-bdd-ng/tree/default/tests/e2e