Skip to content

Pytest classmethod fixtures with scope='class' no longer save class variables. #4949

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
xNinjaKittyx opened this issue Mar 18, 2019 · 2 comments

Comments

@xNinjaKittyx
Copy link

This might not be a bug, and it might have just been a workaround, that has been properly fixed. If it has, please let me know how to migrate to a proper write of the test.

At our work, we wrote many tests like this ever since fixtures were introduced:

class TestClass:

    @classmethod
    @pytest.fixture(scope='class', autouse=True)
    def some_setup_fixture(cls):
        print('ran fixture')
        cls.example = 'hello world'

    def test_1(self):
        print('run test')
        print(cls.example)

    def test_2(self):
        print('run test2')
        print(cls.example)

In this scenario, we want the fixture to only run once per class, but we also want to keep a context of the class.

however, starting from Pytest > 3.7.0 (and all 4 versions), this no longer works. The context is completely removed:

λ pytest -svx test.py
================================================================== test session starts ==================================================================
platform win32 -- Python 3.6.5, pytest-3.7.1, py-1.8.0, pluggy-0.9.0 -- REDACTED\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Windows-10-10.0.14393-SP0', 'Packages': {'pytest': '3.7.1', 'py': '1.8.0', 'pluggy': '0.9.0'}, 'Plugins': {'xdist': '1.26.1', 'metadata': '1.8.0', 'json-report': '0.7.0', 'html': '1.20.0', 'forked': '1.0.2', 'cov': '2.6.1', 'asyncio': '0.10.0', 'pylama': '7.6.6'}}
rootdir: C:\Users\daniel.ahn\Documents\star, inifile:
plugins: xdist-1.26.1, metadata-1.8.0, json-report-0.7.0, html-1.20.0, forked-1.0.2, cov-2.6.1, asyncio-0.10.0, pylama-7.6.6
collected 1 item                                                                                                                                         

test.py::TestClass::test_1 ran fixture
run test
FAILED

======================================================================= FAILURES ========================================================================
___________________________________________________________________ TestClass.test_1 ____________________________________________________________________

self = <test.TestClass object at 0x000001F4A8E4C748>

    def test_1(self):
        print('run test')
>       print(self.example)
E       AttributeError: 'TestClass' object has no attribute 'example'

test.py:15: AttributeError
=============================================================== 1 failed in 0.12 seconds ================================================================

Strange that fixture runs, but whatever variables it sets, pytest doesn't seem to care.

Looking at the submitted changelog, nothing seems to stick out.

removing scope='class' and @classmethod allows us to use the fixture on the newer versions, but it'll run for every single function in the class, which is not the behavior we want.

So two questions:

  1. Is this style of writing tests unwanted? Is it invalid?
  2. If it's invalid, what is the proper right way to write these kinds of tests? Ideally would like an solution that would require minimal work.

pip list:

Package                  Version       Location
------------------------ ------------- ----------------------------------
aiofiles                 0.4.0
aiohttp                  3.5.4
alabaster                0.7.12
apipkg                   1.5
asn1crypto               0.24.0
async-timeout            3.0.1
asyncssh                 1.16.0
atomicwrites             1.3.0
attrs                    19.1.0
Babel                    2.6.0
bcrypt                   3.1.6
boto3                    1.9.111
botocore                 1.12.111
certifi                  2018.11.29
cffi                     1.12.2
chardet                  3.0.4
Click                    7.0
cmd2                     0.9.10
colorama                 0.4.1
coverage                 4.5.2
cryptography             2.6.1
decorator                4.3.2
docutils                 0.14
eradicate                1.0
execnet                  1.5.0
idna                     2.8
idna-ssl                 1.1.0
imagesize                1.1.0
ipython-genutils         0.2.0
Jinja2                   2.10
jmespath                 0.9.4
jsonschema               2.6.0
junitxml                 0.7
jupyter-core             4.4.0
limits                   1.3
MarkupSafe               1.1.0
mccabe                   0.6.1
more-itertools           6.0.0
multidict                4.5.2
mypy                     0.670
mypy-extensions          0.4.1
nbformat                 4.4.0
netmiko                  2.3.3
numpy                    1.16.2
packaging                19.0
paramiko                 2.4.2
pip                      18.1
plotly                   3.6.0
pluggy                   0.9.0
plumbum                  1.6.7
psutil                   5.6.0
py                       1.8.0
pyasn1                   0.4.5
pycodestyle              2.5.0
pycparser                2.19
pydocstyle               3.0.0
pyflakes                 2.1.1
Pygments                 2.3.1
pylama                   7.6.6
pylogbeat                1.0.2
pymongo                  3.7.2
PyNaCl                   1.3.0
pyparsing                2.3.1
pyperclip                1.7.0
pyreadline               2.1
pyserial                 3.4
pytest                   3.7.1
pytest-asyncio           0.10.0
pytest-cov               2.6.1
pytest-cover             3.0.0
pytest-coverage          0.0
pytest-forked            1.0.2
pytest-html              1.20.0
pytest-json-report       0.7.0
pytest-metadata          1.8.0
pytest-xdist             1.26.1
python-dateutil          2.8.0
python-logstash-async    1.5.0
python-rapidjson         0.7.0
pytz                     2018.9
pyvmomi                  6.7.1.2018.12
PyYAML                   3.13
pyzmq                    18.0.1
requests                 2.21.0
retrying                 1.3.3
rpyc                     4.0.2
s3transfer               0.2.0
scp                      0.13.0
setuptools               40.6.3
six                      1.12.0
snowballstemmer          1.2.1
Sphinx                   1.8.4
sphinx-autodoc-typehints 1.6.0
sphinxcontrib-websupport 1.1.0
textfsm                  0.4.1
toml                     0.10.0
traitlets                4.3.2
typed-ast                1.3.1
typing-extensions        3.7.2
urllib3                  1.24.1
wcwidth                  0.1.7
wheel                    0.32.3
xmltodict                0.12.0
xxhash                   1.3.0
yarl                     1.3.0
@xNinjaKittyx xNinjaKittyx changed the title Pytest fixtures with scope='class' inside a class no longer work Pytest classmethod fixtures with scope='class' no longer save class variables. Mar 18, 2019
@nicoddemus
Copy link
Member

Hi @xNinjaKittyx,

Unfortunately this is a duplicate of #3778. We have an attempt to fix it in #3781, but unfortunately that was not successful.

I'm closing this as duplicate then, please subscribe to the original issue to follow if we ever fix it. 😕

@nicoddemus
Copy link
Member

Btw, here's a simple workaround: #3778 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants