Any way to pass parameters to pytest fixture?

I'm not talking about parameterizing the fixture function , which allows you to repeatedly run the device for a hard-set set of parameters.

I have many tests that follow the pattern, for example:

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 is an API client, and includes custom, significant exceptions that wrap urllib2 errors in something specific to the API. So, I have this model - fixing some methods and setting side effects for one of them. I probably use it in a dozen different tests, and the only differences are the three variables that are used in the side_effect part and the MyClass () method that I call.

Is there any way to do this pytest fixture and pass these variables?

+6
source share
3 answers

You can use indirect parameterization 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_file will be executed before the test with the desired parameters

+15
source

I have done even more research on this, as I am posting my question, and the best I can come up with is:

Lamps do not work this way. Just use a regular function, i.e.:

 def my_fixture(httpcode, message, url): 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() return (connection, mock_request, mock_urlopen) def test_something(): connection, mock_req, mock_urlopen = my_fixture(401, 'some message', 'some url') with pytest.raises(MyException): connection.some_function() # this changes 
+6
source

I know this is old, but maybe it helps someone who stumbled upon it again

 @pytest.fixture def data_patcher(request): def get_output_test_data(filename, as_of_date=None): # a bunch of stuff to configure output return output def teardown(): pass request.addfinalizer(teardown) return get_output_test_data 

and then inside the function:

 with patch('function to patch', new=data_patcher): 
+1
source

Source: https://habr.com/ru/post/981222/


All Articles