Search code examples
pytestfixtures

pytest: How do I read a list of fixtures from a file?


I would like to pytest (via TestInfra) to assert the presence of packages on a host. I have a list of packages that should be there in a text file, which I can read and put in an array. I would like to use that array to parametrize a fixture, so that I can use it in a test.

Something like:

@pytest.fixture
def packages():
    listfile = open("list.txt", "r")
    packages = listfile.read().splitlines()
   return packages

and then use it to parametrize a test:

@pytest.mark.parametrize("name", packages)
    def test_packages(host, name):
    assert host.package(name).is_installed

The error I'm getting is

    /home/becker/molecule/local/lib/python2.7/site-packages/pluggy/__init__.py:617: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
/home/becker/molecule/local/lib/python2.7/site-packages/pluggy/__init__.py:222: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
/home/becker/molecule/local/lib/python2.7/site-packages/pluggy/__init__.py:216: in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
/home/becker/molecule/local/lib/python2.7/site-packages/_pytest/python.py:197: in pytest_pycollect_makeitem
    res = list(collector._genfunctions(name, obj))
/home/becker/molecule/local/lib/python2.7/site-packages/_pytest/python.py:390: in _genfunctions
    self.ihook.pytest_generate_tests(metafunc=metafunc)
/home/becker/molecule/local/lib/python2.7/site-packages/pluggy/__init__.py:617: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
/home/becker/molecule/local/lib/python2.7/site-packages/pluggy/__init__.py:222: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
/home/becker/molecule/local/lib/python2.7/site-packages/pluggy/__init__.py:216: in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
/home/becker/molecule/local/lib/python2.7/site-packages/_pytest/python.py:122: in pytest_generate_tests
    metafunc.parametrize(*marker.args, **marker.kwargs)
/home/becker/molecule/local/lib/python2.7/site-packages/_pytest/python.py:809: in parametrize
    argnames, argvalues, self.function, self.config)
/home/becker/molecule/local/lib/python2.7/site-packages/_pytest/mark/structures.py:102: in _for_parametrize
    for x in argvalues]
E   TypeError: 'function' object is not iterable
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=========================== 1 error in 0.41 seconds ============================

Solution

  • Currently, pytest doesn't support passing fixtures as parameters to pytest.mark.parametrize. You can track the current status of the related discussion in issue #349.

    However, fixtures are functions too. So, as suggested in the comments, you can simply call the fixture function in parametrize:

    @pytest.mark.parametrize("name", packages())
    def test_packages(host, name):
        ...