diff --git a/CHANGES.rst b/CHANGES.rst index 7e74497..131eb5f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,7 @@ Unreleased - Add ``stacklevel`` param to ``given``, ``when``, ``then``, ``step`` decorators. This allows for programmatic step generation `#548 `_ - Hide pytest-bdd internal method in user tracebacks `#557 `_. - Make the package PEP 561-compatible `#559 `_ `#563 `_. +- Configuration option ``bdd_features_base_dir`` is interpreted as relative to the `pytest root directory `_ (previously it was relative to the current working directory). `#573 `_ 6.0.1 diff --git a/README.rst b/README.rst index f8a450b..e0af67e 100644 --- a/README.rst +++ b/README.rst @@ -801,7 +801,7 @@ then Feature file paths ------------------ -By default, pytest-bdd will use current module's path as base path for finding feature files, but this behaviour can be changed in the pytest configuration file (i.e. `pytest.ini`, `tox.ini` or `setup.cfg`) by declaring the new base path in the `bdd_features_base_dir` key. The path is interpreted as relative to the working directory when starting pytest. +By default, pytest-bdd will use current module's path as base path for finding feature files, but this behaviour can be changed in the pytest configuration file (i.e. `pytest.ini`, `tox.ini` or `setup.cfg`) by declaring the new base path in the `bdd_features_base_dir` key. The path is interpreted as relative to the `pytest root directory `__. You can also override features base path on a per-scenario basis, in order to override the path for specific tests. pytest.ini: diff --git a/src/pytest_bdd/scenario.py b/src/pytest_bdd/scenario.py index 54cce5a..7dad2f3 100644 --- a/src/pytest_bdd/scenario.py +++ b/src/pytest_bdd/scenario.py @@ -287,8 +287,11 @@ def scenario( def get_features_base_dir(caller_module_path: str) -> str: - default_base_dir = os.path.dirname(caller_module_path) - return get_from_ini("bdd_features_base_dir", default_base_dir) + d = get_from_ini("bdd_features_base_dir", None) + if d is None: + return os.path.dirname(caller_module_path) + rootdir = CONFIG_STACK[-1].rootpath + return os.path.join(rootdir, d) def get_from_ini(key: str, default: str) -> str: diff --git a/tests/feature/test_feature_base_dir.py b/tests/feature/test_feature_base_dir.py index a433b51..5882b22 100644 --- a/tests/feature/test_feature_base_dir.py +++ b/tests/feature/test_feature_base_dir.py @@ -1,4 +1,6 @@ """Test feature base dir.""" +import os + import pytest NOT_EXISTING_FEATURE_PATHS = [".", "/does/not/exist/"] @@ -21,6 +23,19 @@ def test_feature_path_ok(pytester): result.assert_outcomes(passed=2) +def test_feature_path_ok_running_outside_rootdir(pytester): + base_dir = "features" + prepare_testdir(pytester, base_dir) + + old_dir = os.getcwd() + os.chdir("/") + try: + result = pytester.runpytest(pytester.path, "-k", "test_ok_by_ini") + result.assert_outcomes(passed=2) + finally: + os.chdir(old_dir) + + def test_feature_path_by_param_not_found(pytester): """As param takes precedence even if ini config is correct it should fail if passed param is incorrect"""