Pytest fixture with scope “class” running on every method

本秂侑毒 提交于 2019-12-11 03:26:55

问题


I'm trying to create a test environment with Pytest. The idea is to group test methods into classes.

For every class/group, I want to attach a config fixture that is going to be parametrized. So that I can run all the tests with "configuration A" and then all tests with "configuration B" and so on.

But also, I want a reset fixture, that can be executed before specific methods or all methods of a class.

The problem I have there is, once I apply my reset fixture (to a method or to a whole class), the config fixture seems to work in the function scope instead of the class scope. So, once I apply the reset fixture, the config fixture is called before/after every method in the class.

The following piece of code reproduces the problem:

import pytest
from pytest import *

@fixture(scope='class')
def config(request):
    print("\nconfiguring with %s" % request.param)
    yield
    print("\ncleaning up config")

@fixture(scope='function')
def reset():
    print("\nreseting")

@mark.parametrize("config", ["config-A", "config-B"], indirect=True)
#@mark.usefixtures("reset")
class TestMoreStuff(object):

    def test_a(self, config):
        pass

    def test_b(self, config):
        pass

    def test_c(self, config):
        pass

The test shows how the config fixture should work, being executed only once for the whole class. If you uncomment the usefixtures decoration, you can notice that the config fixture will be executed in every test method. Is it possible to use the reset fixture without triggering this behaviour?


回答1:


As I mentioned in a comment, that seems to be a bug in Pytest 3.2.5.

There's a workaround, which is to "force" the scope of a parametrization. So, in this case if you include the scope="class" in the parametrize decorator, you get the desired behaviour.

import pytest
from pytest import *

@fixture(scope='class')
def config(request):
    print("\nconfiguring with %s" % request.param)
    yield
    print("\ncleaning up config")

@fixture(scope='function')
def reset():
    print("\nreseting")

@mark.parametrize("config", ["config-A", "config-B"], indirect=True, scope="class")
@mark.usefixtures("reset")
class TestMoreStuff(object):

    def test_a(self, config):
        pass

    def test_b(self, config):
        pass

    def test_c(self, config):
        pass



回答2:


It depends on which version of pytest you are using.

There are some semantical problems to implement this in older versions of pytest. So, this idea is not yet implemented in older pytest. Someone has already given suggestion to implement the same. you can refer this

"Fixture scope doesn't work when parametrized tests use parametrized fixtures". This was the bug. You can refer this

This issue has been resolved in latest version of pytest. Here's the commit for the same with pytest 3.2.5

Hope it would help you.



来源:https://stackoverflow.com/questions/47312835/pytest-fixture-with-scope-class-running-on-every-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!