I am not talking about the Parameterizing a fixture feature that allows a fixture to be run multiple times for a hard-coded set of parameters.
I have a LOT of tests that follow a pattern like:
httpcode = 401 # this is different per call
message = 'some message' # this is different per call
url = 'some url' # this is different per call
mock_req = mock.MagicMock(spec_set=urllib2.Request)
with mock.patch('package.module.urllib2.urlopen', autospec=True) as mock_urlopen, \
mock.patch('package.module.urllib2.Request', autospec=True) as mock_request:
mock_request.return_value = mock_req
mock_urlopen.side_effect = urllib2.HTTPError(url, httpcode, message, {}, None)
connection = MyClass()
with pytest.raises(MyException):
connection.some_function() # this changes
Essentially, I have a class that's an API client, and includes custom, meaningful exceptions that wrap urllib2 errors in something API-specific. So, I have this one pattern - patching some methods, and setting side effects on one of them. I use it in probably a dozen different tests, and the only differences are the three variables which are used in part of the side_effect, and the method of MyClass() that I call.
Is there any way to make this a pytest fixture and pass in these variables?
You can use indirect fixture parametrization http://pytest.org/latest/example/parametrize.html#deferring-the-setup-of-parametrized-resources
@pytest.fixture()
def your_fixture(request):
httpcode, message, url = request.param
mock_req = mock.MagicMock(spec_set=urllib2.Request)
with mock.patch('package.module.urllib2.urlopen', autospec=True) as mock_urlopen, \
mock.patch('package.module.urllib2.Request', autospec=True) as mock_request:
mock_request.return_value = mock_req
mock_urlopen.side_effect = urllib2.HTTPError(url, httpcode, message, {}, None)
connection = MyClass()
with pytest.raises(MyException):
connection.some_function() # this changes
@pytest.mark.parametrize('your_fixture', [
(403, 'some message', 'some url')
], indirect=True)
def test(your_fixture):
...
and your_fixture will run before test with desired params