pytest-dev / pytest-bdd

BDD library for the pytest runner
https://pytest-bdd.readthedocs.io/en/latest/
MIT License
1.31k stars 221 forks source link

Can't use given fixture in another fixture #428

Open Gaasmann opened 3 years ago

Gaasmann commented 3 years ago

Hello,

I'm trying to use an autouse fixture to do some cleanup after a test. I'm defining a fixture depending of the given step but that doesn't seem to work. I'm not sure why or how to fix that or if this is a bug.

Setup info

(pytestbdd) nicolas@bunker:~/learning/pytestbdd$ pip freeze | grep pytest
pytest==6.2.4
pytest-bdd==4.0.2
(pytestbdd) nicolas@bunker:~/learning/pytestbdd$ python --version
Python 3.9.2

Feature file

Feature: A fake feature
  This is a fake feature

  Scenario: Trying to reference given a a fixture in another fixture
    Given the given step defines a fixture
    When  I check the fixture
    Then  nothing

Steps file

import pytest
from pytest_bdd import scenarios, given, when, then

scenarios("fake.feature")

@given("the given step defines a fixture", target_fixture="the_fixture")
def my_given():
    return "a useless fixture"

@pytest.fixture(autouse=True)
def house_cleaning(the_fixture):
    print(the_fixture)
    yield
    print("cleanup stuff depending on the_fixture")

@when("I check the fixture")
def fixture_check(the_fixture):
    assert the_fixture == "a useless fixture"

@then("nothing")
def nothing(the_fixture):
    pass

pytest --setup-plan result

======================================= ERRORS =======================================
__ ERROR at setup of test_trying_to_reference_given_a_a_fixture_in_another_fixture ___
file /home/nicolas/.virtualenvs/pytestbdd/lib/python3.9/site-packages/pytest_bdd/scenario.py, line 175
          @pytest.mark.usefixtures(*function_args)
          def scenario_wrapper(request):
file /home/nicolas/learning/pytestbdd/test_main.py, line 12
  @pytest.fixture(autouse=True)
  def house_cleaning(the_fixture):
E       fixture 'the_fixture' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, house_cleaning, monkeypatch, pytestbdd_given_the given step defines a fixture, pytestbdd_given_trace, pytestbdd_then_nothing, pytestbdd_then_trace, pytestbdd_when_I check the fixture, pytestbdd_when_trace, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/home/nicolas/learning/pytestbdd/test_main.py:12
============================== short test summary info ===============================
ERROR test_main.py::test_trying_to_reference_given_a_a_fixture_in_another_fixture
================================== 1 error in 0.02s ==================================

If you look at the list of available fixtures, you'll see "pytestbdd_given_the given step defines a fixture", I'm not sure how to use/reference that one or if it would work like the_fixture but it seems pytest is somehow aware of the given step.

Thanks

elchupanebrej commented 3 years ago

Step defined fixture is injected after module/conftest/plugin fixtures. Just one reason to use target_fixture is to modify an already defined environment for the test. You could define "the_fixture" as the usual pytest fixture and modify it from the given step.