[TIP] get fixtures for each parameter or global variables?

holger krekel holger at merlinux.eu
Sat Oct 22 10:40:46 PDT 2016


Hey James,

IMO there is no need to have global variables at all and in fact your example becomes simpler without it ... let me first cite your example code before i write down a substitute:

On Fri, Oct 21, 2016 at 20:02 -0400, James wrote:
> # conftest.py
> import pytest
> 
> @pytest.fixture(scope='module')
> def a(request):
>     value = request.config.getoption("A")
>     if not value:
>         pytest.skip('test needs -A option to run')
>     return value
> 
> class global_vars():
>     def __init__(self):
>         self.a=''
>         self.b=''
> 
> 
> @pytest.fixture(scope='module')
> def get_globals():
>     gv=global_vars()
>     gv.a = pytest.config.getoption("A")
>     gv.b = pytest.config.getoption("B")
>     return gv
> 
> def pytest_addoption(parser):
>     parser.addoption("--A", action="store", default=None, help="a option")
>     parser.addoption("--B", action="store", default=None, help="b option")
> 
> import inspect
> import pytest
> 
> # testscript.py
> 
> 
> @pytest.mark.usefixtures('get_globals')
> class TestAclass():
>     def test_1(self):
>         print 'inside {0}-{1}
> step'.format(self.__class__.__name__,inspect.currentframe().f_code.co_name)
>         gv=get_globals()
>         print 'a={0}, b={1}'.format(gv.a, gv.b)
>         pass

Here is how i would write the equivalent without any concept of global state:

    # conftest.py
    def pytest_addoption(parser):
        parser.addoption("--A", action="store", default=None, help="a option")
        parser.addoption("--B", action="store", default=None, help="b option")

    @pytest.fixture(scope="module")
    def a(pytestconfig):
        return pytestconfig.getoption("A", skip=True)

    @pytest.fixture(scope="module")
    def b(pytestconfig):
        return pytestconfig.getoption("B", skip=True)

    # testscript.py
    class TestAClass:
        def test_1(self, a, b, request):
            print 'inside {0}-{1} step'.format(
              self.__class__.__name__, request.function.__name__)

            print 'a={0}, b={1}'.format(a, b)

  
The test_1 function can simply use the "a" and "b" argument names in order to use the fixtures defined in the conftest.py file.  pytest was specifically designed to avoid global state. In fact, pytest keeps no global state whatsoever internally.

holger



More information about the testing-in-python mailing list