Question: I'm writing some unit tests using Pytest and came across two ways to parameterize test inputs. One is using parametereized fixtures and the other is using the pytest.mark.parametrize method. The two examples I have are: # method 1 def tokens(): yield from ["+", "*", "?"] @pytest.mark.parametrize("token", tokens()) def test_stuff(token): assert stuff  and # method 2 @pytest.fixture(params=["+", "*", "?"]) def token(request): return request.param def test_stuff(token): assert stuff  Both have different advantages and disadvantages from what I can tell: Method 1 Advantages  Supports multiple parameters Supports lazy evaluation  Disadvantages  More boilerplate code when used for multiple test methods requires explicit parameter mapping for every method used, even if parameters are the same name  method 2 Advantages  Less Boiler Plate code  Disadvantages  Only allows single parameter to be passed to unit test  I'm still new to PyTest so maybe there is a way around the disadvantages that I listed above for each method but given those I have been having a hard time trying to decide which one to use. I would guess that the intended way to do what I am trying to do is to use @pytest.mark.parametrize but when passing only a single parameter having less boilerplate code by using a fixture seems like a big advantage. Can anyone tell me a reason not to do it this way or is this a perfectly valid use case?

Answer: As pk786 mentions in his comment, you should use a fixture "...if you have something to set up and teardown for the test or using (the) same dataset for multiple tests then use fixture". For example, you may want to load several datasets that you test against in different test functions. Using a fixture allows you to only load these datasets once and share them across the test functions. You can use params argument of @pytest.fixture to load and cache each dataset. Then, the test functions that use those fixtures will run against each loaded dataset. In code, this might look something like: import json import pytest test_files = ["test_file1.json", "test_file2.json"] @pytest.fixture(params=test_files) def example_data(request): with open(request.param, "r") as f: data = json.load(f) return data def test_function1(example_data): # run test with example data. # this test will be run once for each file in the list `test_files` above. ... def test_function2(example_data): # run a different test with example data. # this test will be run once for each file in the list `test_files` above. # this test takes advantage of automatic caching mechanisms of fixtures... # ...so that data is not loaded again. ...  Alternatively, as pk786 states, "If you are using a set of data only once, then @pytest.mark.parametrize should be the approach". This statement applies to the example that you provided since you are not performing any setup in the fixture that you need to share across test. In this case, even if you are using the "tokens" across multiple tests, I would consider decorating each function with @pytest.mark.parameterize since I believe this approach more explicitly states your intent and will be easier to understand for anyone else reading your code. This would look like this: ... def tokens(): yield from ["+", "*", "?"] @pytest.mark.parametrize("token", tokens()) def test_stuff(token): assert stuff @pytest.mark.parametrize("token", tokens()) def test_other_stuff(token) assert other_stuff