I want to parametrize a test with fixtures. Something like this:
def count_lines(path):
with open(path, 'r') as fh:
return len(fh.readlines())
@pytest.fixture
def data_path():
return '/path/to/test/data'
@pytest.fixture
def simple_file(data_path):
return os.path.join(data_path, 'simpletestfile.ext')
@pytest.fixture
def other_file(data_path):
return os.path.join(data_path, 'othertestfile.ext')
@pytest.mark.parametrize('given, expected', [
(simple_file, 3),
(other_file, 9),
])
def test_count_lines(given, expected):
observed = count_lines(given)
assert observed == expected
The code above fails because instead of resolving the sample_file
and other_file
fixtures, the test receives the functions which makes the test fail at the open()
statement.
To make it work I have to do something like this:
@pytest.mark.parametrize('given, expected', [
(simple_file(data_path()), 3),
(other_file(data_path()), 9),
])
But that seems to defeat the purpose of py.test.
Another alternative is
class TestCountLines(object):
TESTDATA = [
{
'id': 'simple case',
'input_file': 'simpletestfile.ext',
'expected': 3,
},
{
'id': 'other case',
'input_file': 'othertestfile.ext',
'expected': 9,
},
]
@pytest.fixture(params=TESTDATA, ids=lambda x: x['id'])
def staged_testdata(self, request, data_path):
datafile = os.path.join(data_path, request.param['input_file'])
expected = request.param['expected']
yield datafile, expected
def test_count_lines(self, staged_testdata):
given, expected = staged_testdata
observed = count_lines(given)
assert observed == expected
Yet I find that the code above is curious because the staged_testdata
fixture yields two things and then I need to unpack the test data before testing. So, how do I parametrize a test with fixtures?