Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Same dict variable value updated between tests in pytest

I have 2 tests that use the same dict for data. But when I update something in 1 test that will affect the second test. I want them to be independent.

data.py

a = {"data": {'data1': 'mydata',
              'data2': 'mydata2'
              }
     }

test_mytest.py

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

from data import a
import pytest

def test_1():
    test_data = a['data']
    test_data['data1'] = 'new data'


def test_2():
    test_data = a['data']
    assert test_data['data1'] == 'mydata'

When I run test_2 only it passes. But when I run both using pytest, test_2 is failing.
I want them to be passed when running together. Also, what can be the best way of doing this?

>Solution :

Global mutable state is something best avoided in testing. There are no guarantees about the order in which your tests will be executed, and sharing state between tests can prevent speeding up the test suite by using a plugin like pytest-xdist (which executes tests in parallel).

Instead, I would do it like this, giving each test a copy of the data by using a fixture

import pytest

@pytest.fixture
def a():
    return {
        "data": {
            "data1": "mydata",
            "data2": "mydata2",
        }
    }

def test_1(a):
    test_data = a['data']
    test_data['data1'] = 'new data'

def test_2(a):
    test_data = a['data']
    assert test_data['data1'] == 'mydata'

If the data must be externally available:

# in conftest.py

import pytest
import copy

from data import a as a_source

@pytest.fixture
def a():
    return copy.deepcopy(a_source)

Note that if tests need to modify data.a itself, rather than providing a modified copy of a when calling a function for example, then you may prefer to simply patch the object in each test using pytest’s monkeypatch fixture or using pytest-mock plugin, e.g.:

def test_2(mocker):
    mocker.patch("data.a", {"k": "v"})
    ...

This kind of runtime patching only works if the contents of data.a are accessed by the code under test (i.e. not at import time). If it was already accessed before your test runs, then you’re too late to patch.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading