session scope with pytest-mock

Question:

I’m looking for example of how to use the session-scoped "session-mocker" fixture of the pytest-mock plugin.

It’s fairly clear how to modify the example the docs provide to use it in a particular test:

def test_foo(session_mocker):
    session_mocker.patch('os.remove')
    etc...

But I’m baffled as to where and how this global fixture should be initialized. Say, for example, that I want to mock "os.remove" for ALL of my tests. Do I set this up in confftest.py and, if so, how do I do it?

Asked By: Gadzooks34

||

Answers:

You use it in a fixture with a scope of session. The best place to put it would be conftest.py. That’s mainly to make it obvious to other programmers that this fixture exists and what it might be doing. That’s important because this fixture will effect other tests that might not necessarily know about this fixture or even want it.

I wouldn’t recommend mocking something for the duration of a session. Tests, classes or even modules, yes. But not sessions.

For instance, the following test test_normal passes or fails depending on whether test_mocked was run in the same session or not. Since they’re in the same "file", it’s much easier to spot the problem. But these tests could be located in different test files, that do not appear related, and yet if both tests were run in the same session then the problem would occur.

import pytest

# could be in conftest.py
@pytest.fixture(scope='session')
def myfixture(session_mocker):
    session_mocker.patch('sys.mymock', create=True)

def test_mocked(myfixture):
    import sys
    assert hasattr(sys, 'mymock')

def test_normal():
    import sys
    assert not hasattr(sys, 'mymock')

Instead, just create a fixture that is scoped for test, class or module, and include it directly in the test file. That way the behaviour is contained to just the set of tests that need it. Mocks are cheap to create, so having the mock recreated for every test is no big deal. It may even be beneficial, as the mock will be reset for each test.

Save session fixtures for things that are expensive to setup, and which have no state, or that the tests do not change its state (eg. a database that is used as a template to create a fresh database that each test will run against).

Answered By: Dunes
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.