orion_tvv orion_tvv - 15 days ago 5
Python Question

Python. Pytest fixture collision

I'm trying use

pytest yield-fixture
with the default scope multiple times in one test.

@pytest.fixture
def create_temp_file():
nonlocal_maker_data = {'path': None} # nonlocal for python2

def maker(path, data):
nonlocal_maker_data['path'] = path
with open(path, 'wb') as out:
out.write(data)
try:
yield maker
finally:
path = nonlocal_maker_data['path']
if os.path.exists(path):
os.remove(path)


def test_two_call_of_fixture(create_temp_file):
create_temp_file('temp_file_1', data='data1')
create_temp_file('temp_file_2', data='data2')

with open('temp_file_1') as f:
assert f.read() == 'data1'

with open('temp_file_2') as f:
assert f.read() == 'data2'

assert False
# temp_file_2 removed
# temp_file_1 doesn't removed


I have a collision. The first fixture doesn't clean - temp_file_1 doesn't remove, while the second file removed well.
Is is possible to use fixture many times correct?

PS: I know about
tmpdir
- standart pytest fixture. This is just an example.

Answer

Fixture yeilds a function in this example. I think that the straight way is to accumulate passed args:

@pytest.fixture
def create_temp_file():
    nonlocal_maker_data = set()  # nonlocal for python2

    def maker(path, data):
        with open(path, 'wb') as out:
            out.write(data)
        nonlocal_maker_data.add(path)
    try:
        yield maker
    finally:
        for path in nonlocal_maker_data:
            if os.path.exists(path):
                os.remove(path)
Comments