-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add possibility to pass parameter to the fixture from another fixture #1694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Currently there's no way to pass parameters to fixtures from within a test function or other fixtures, by that point the fixture function has already been called. Usually the solution to this is to make a fixture return an object or function which you can call from within a test function and does what you need. @pytest.fixture(scope='session')
def fixture_1(request):
def do_it(param):
# do something
return do_it
@pytest.fixture
def fixture_2(fixture_1): #
result = fixture_1(some_param) IOW the fixture becomes a factory function that you can call at any time. Does that look reasonable to you? |
I do have a similar situation, where I need to pass a fixture as a params of another fixture. Is there any solution for me? Unfortunately I can't create my ValueProvider instance outside the fixture class ValueProvider(object):
def __init__(self):
self.range = range(10)
@property
def values(self):
return self.range
@pytest.fixture(scope="session")
def fxArgProvider(request):
obj = ValueProvider()
#Note: I have to create this object as part of fixture in my use case;
# Can't make it as module variable
return obj
@pytest.mark.parametrize("value", fxArgProvider.values)
def test_rangeOfValues(value):
# test logic
assert value=="" |
@satishmovvar take a look at pytest-lazy-fixture. |
@nchammas thanks for the suggestion, but this still doesn't solve my problem. the lazy fixture returns an object with only one value for parametrize. I want to use a list of values from the fixture which is used as params in the test. below code work with lazy fixture but that's not what I want. @pytest.fixture(scope="class", params=[2,4,8])
def values(request):
return request.param
@pytest.mark.parametrize('n_iter', [pytest.lazy_fixture("values")])
class Test_Class1: instead I want something like below: @pytest.fixture(scope="class")
def values(request):
return [2,4,6]
@pytest.mark.parametrize('n_iter', pytest.lazy_fixture("values"))
class Test_Class1: in which I get error "TypeError: 'LazyFixture' object is not iterable". I found an open question in StackOverflolw similar to my scenario -https://stackoverflow.com/questions/50482416/use-pytest-lazy-fixture-list-values-as-parameters-in-another-fixture |
@sathishaMovvar - You pinged me but I think you meant to ping @nicoddemus instead. |
@sathishaMovvar currently this is simply impossible - parameterization happens before any fixture is ever made |
@RonnyPfannschmidt But what if on the parameterization stage we could define that parameter is another fixture, and retrieve its value only on the actual call assuming that it was previously executed and has a result already? This is how I actually solved my problem. I was passing only fixture name into another fixture as a parameter, and, using reflection, retrieved its the value on the call. It was kinda dirty, but it worked. |
@OlegKuzovkov at a work project we have a plugin providing parameter ids and actual values to parameterization in a controlled manner - there is no need to magically have some fixutures at collect time |
@RonnyPfannschmidt Good, but at our working project we use fixtures to execute different pieces of logic, grab the output and use it further in tests/fixtures. Some of those fixtures are parametrized, and we are passing the values to those from the tests using undirect=True flag in parametrized decorator. At some point, we faced the scenario where we had to execute the fixture with certain parameters and pass the output object to another one. |
that use-case is unsupported then ^^ |
That method removes a huge advantage of fixtures: assertions/exceptions from fixtures will result in a test error. Fixtures are a great place to put in sanity tests to make sure the the system under test is in a valid state, to separately validate test resources outside of the tests themselves. This improves analysis and allows fixtures to act as gatekeepers to prevent wasting time executing tests that will fail without special intervention (such as issues from a power outage, build failure, unplugged cables, or IP address change). However, the nested function acts like a regular/test function and not a fixture. Most critically: assertions/exceptions get reported as failures, and thus mixed up with test results. For complex test systems, this wastes a lot of analysis time to discover which reported "Failure"(s) is actually an "Error." |
@designerzim an alternative would be to use custom exceptions instead of assertions in that case. It would probably improve code readability because you can have an hierarchy of exceptions with various error conditions. Those exceptions would be an Error regardless if they executed in a fixture or test then. Otherwise I believe we can close this discussion? |
Could you please implement possibility to pass parameter from one fixture to the parent one?
I have a complex fixture hierarchy in my test framework. I have some cases when i really need to have this feature.
Example:
So far I can pass parameter to the fixture from test using:
Need to have exactly the same thing from fixture.
Thank you!
The text was updated successfully, but these errors were encountered: