pytestpytest-fixtures

how to make a pytest plugin fixture overridable by user?


I'm building a pytest plugin that creates a tree with the Google Earth Engine API. The idea being that the plugin will manage both the creation and the deletion of this tree from the developer account.

To do so I use a fixture in my plugin.py that define the content of the said tree. by default it's empty:

# plugin.py

@pytest.fixture(scope="session")
def folder_structure():
    return {} 

I would like to give the user, the option to override this structure by setting it's own fixture with the same name. My understanding of pytest documentation on plugins is that conftest.py will have priority:

# conftest.py

@pytest.fixture(scope="session")
def folder_structure():
    return {"toto": {
        "tutu": "<a GEE API object>"
        } 
    }

But when I try to test it in my test suit it fails:

def test_folder_structure(folder_structure):
    assert len(folder_structure) > 0

Is my understanding wrong and is there another workaround I could use to achieve this behaviour ?


Solution

  • My understanding was correct, there was simply a typo in my conftest.py function name. As the question remains relevant I'll summarize the methodology here:

    Set variables as a fixture

    You want to create a plugin and make some variables accessible to the test developer, e.g. change a key, change the value of a threshold etc....

    A simple solution is to store these variable as fixtures in your plugin and make the other fixtures rely on it:

    # plugin.py 
    
    @pytest.fixture(scope="session")
    def hash_key():
        return uuid4().hex
    
    @pytest.fixture(scope="session")
    def random_folder(hash_key):
       return Path(hash_key)
    

    override

    as shown in this graph from the pytest documentation:

    graph

    plugins are the last to be check when resolving fixtures so to override their values simply redefine them in lower area like conftest.py:

    # conftest.py
    
    @pytest.fixture(scope="session")
    def hash_key():
        return uuid4().hex[:6]
    

    and now in your test the hash key will always be shorter:

    # test_something.py 
    
    def test_hash_key(hash_key):
        assert len(hash_key) == 6