简体   繁体   中英

How to apply fixture from conftest.py to inner folders only

I have a fixture that located in conftest.py.

@pytest.fixture(scope='module', autouse=True) 
def my_fixture():
    """
    Some useful code
    """

The structure is like below:

tests
 |
 |--first_folder
 |   |--__init__.py
 |   |--test_first_1.py
 |   |--test_first_2.py
 |   
 |--second_folder
 |   |--__init__.py
 |   |--test_second_1.py
 |
 |--__init__.py   
 |--conftest.py
 |--test_common_1.py

I want that fixture to be auto-used in inner folders test scripts only: in test_first_1.py , test_first_2.py , test_second_1.py , but NOT in test_common_1.py .

I can create conftest with that fixture in each inner folder, but I don't want to duplicate the code

Is there any way to apply fixture from conftest to test scripts from inner folders and ignore it in common folder test scripts?

One possible solution, is you do not want to change the structure of your folders, is that you use the request object in your fixture to check the markers used on the test, so you do anything if a specific marker is set:

@pytest.fixture(scope='module', autouse=True) 
def my_fixture(request):
    """
    Some useful code
    """
    if 'noautofixt' in request.keywords:
        return
    # more code

Then mark your tests as follows:

@pytest.mark.noautofixt
def test_no_running_my_fixture():
    pass

You can achive this by moving the folders 'first folder' and 'second folder' to a new folder and have a conftest.py file in that new folder. Like this -

tests
 |
 |--new folder
 |  |--first_folder
 |  |  |--__init__.py
 |  |  |--test_first_1.py
 |  |  |--test_first_2.py
 |  |
 |  |--second_folder
 |  |  |--__init__.py
 |  |  |--test_second_1.py
 |  |--conftest.py
 |
 |--__init__.py   
 |--conftest.py
 |--test_common_1.py

If you want to autouse a top-level conftest fixture for only a subset of your test modules, the guidance is to make use of the global variable pytestmark (reference: pytestmark ; tutorial: Marking whole classes or modules ).

In your case, you'll want to disable autouse for your fixture defined in tests/conftest.py :

# tests/conftest.py
import pytest

@pytest.fixture(scope='module') 
def my_fixture():
    """
    Some useful code
    """

Then in whatever module you'd like to enable autouse of it, set the global variable pytestmark eg

# tests/first_folder/test_first_1.py
import pytest

pytestmark = pytest.mark.usefixtures('my_fixture')

def test_first_feature():
    result = something(my_fixture)  # autouse of my_fixture
    assert result == expected

@lmiguelvargasf answer (+1) pointed me in the right direction and using request I solved the issue as below:

@pytest.fixture(scope='module', autouse=True)
def my_fixture(request):
    if request.config.invocation_dir.basename != 'tests':
        """
        Some useful code
        """

This fixture will be applied only to test-scripts from inner folders as invocation folder name is not equal to 'tests'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM