Passing (yield) fixtures as test parameters (with a temp directory)

后端 未结 3 1051
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-20 11:02

Question

Is it possible to pass yielding pytest fixtures (for setup and teardown) as parameters to test functions?

Context

I\'m testing an object th

3条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-20 11:34

    Try making your data function / generator into a fixture. Then use request.getfixturevalue() to dynamically run the named fixture.

    import pytest, tempfile, os, shutil
    from contextlib import contextmanager
    
    @pytest.fixture # This works with pytest>3.0, on pytest<3.0 use yield_fixture
    def datadir():
        datadir = tempfile.mkdtemp()  # setup
        yield datadir
        shutil.rmtree(datadir)        # teardown
    
    class Thing:
        def __init__(self, datadir, errorfile):
            self.datadir = datadir
            self.errorfile = errorfile
    
    
    @pytest.fixture
    def thing1(datadir):
        errorfile = os.path.join(datadir, 'testlog1.log')
        yield Thing(datadir=datadir, errorfile=errorfile)
    
    @pytest.fixture
    def thing2(datadir):
        errorfile = os.path.join(datadir, 'testlog2.log')
        yield Thing(datadir=datadir, errorfile=errorfile)
    
    @pytest.mark.parametrize('thing_fixture_name', ['thing1', 'thing2'])
    def test_attr(request, thing):
        thing = request.getfixturevalue(thing) # This works with pytest>3.0, on pytest<3.0 use getfuncargvalue
        print(thing.datadir)
        assert os.path.exists(thing.datadir)
    

    Going one step futher, you can parametrize the thing fixtures like so:

    class Thing:
        def __init__(self, datadir, errorfile):
            self.datadir = datadir
            self.errorfile = errorfile
    
    @pytest.fixture(params=['test1.log', 'test2.log'])
    def thing(request):
        with tempfile.TemporaryDirectory() as datadir:
            errorfile = os.path.join(datadir, request.param)
            yield Thing(datadir=datadir, errorfile=errorfile)
    
    def test_thing_datadir(thing):
        assert os.path.exists(thing.datadir)
    

提交回复
热议问题