-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Parametrize based on another parameter #4050
Comments
covariant parameterize is long-sought ^^ |
Gave a quick and dirty stab at this: # conftest.py
import attr
import pytest
@attr.s
class Covariant:
name = attr.ib()
values = attr.ib()
def make_fixture(self):
@pytest.fixture(name=self.name, params=self.values)
def fixture_func(request):
return request.param
return fixture_func
def pytest_configure():
pytest.covariant_param = Covariant
@pytest.hookimpl(hookwrapper=True)
def pytest_collect_file():
outcome = yield
modules = outcome.get_result()
for module in modules:
if isinstance(module, pytest.Module):
print(module)
for name in dir(module.obj):
member = getattr(module.obj, name)
if isinstance(member, Covariant):
fixture = member.make_fixture()
setattr(module.obj, name, fixture)
print(fixture)
module.session._fixturemanager.parsefactories(module) Usage: import pytest
dataset = pytest.covariant_param('dataset', [1, 2, 3])
def test_foobar(dataset):
pass
But the idea is to do some post processing after collection, where we look for It needs some refining to collect from test classes as well, possibly other features like scope and ids, but I believe the underlying implementation is surprisingly solid because we are using fixtures behind the scenes. It might be missing some functionality as I only tested with This can easily be done in an external plugin too. |
Hey @nicoddemus that is really interesting! |
Sorry about that, wrote that right before going to bed.
You mean this last example right? # Following line is almost as if we are parametrizing the parametrize
# So it will be doubly parametrized:
# test_data[datasetA-data1_a]
# test_data[datasetA-data2_a]
# test_data[datasetA-data3_a]
# test_data[datasetB-data1_b]
# test_data[datasetC-data1_c]
# test_data[datasetC-data2_c]
@pytest.mark.parametrize('data', pytest.parameter('dataset')])
def test_data(data):
#do test Perhaps extending the idea further, I think this might be possible to implement: import pytest
datasetA = pytest.covariant_param('datasetA', ['data1_a', 'data2_a', 'data3_a'])
datasetB = pytest.covariant_param('datasetB', ['data1_b'])
datasetC = pytest.covariant_param('datasetC', ['data1_c', 'data2_c'])
dataset = pytest.covariant_param('dataset', [datasetA, datasetB, datasetC])
def test_foobar(dataset):
pass What do you think? |
If it results in the set of tests described in the comments above the test function, then I think it should do the job! Probably we would have to iterate a bit to get the interface 100% correct but it seems to be going in the right direction |
Just for the sake of traceability, @Sup3rGeo you requested this feature in Note: when it is officially fixed in pytest the pytest-cases version will fallback on it, but I will keep the current implementation available for older versions of pytest. |
Hi,
This feature is related to a concept I think that pytest is missing. Let's say I have this very simple test:
Now, I want to refactor the setup as a fixture, but still have the same parametrization for both the test and the fixture. In that case, I end up having to create a fixture:
So basically the concept that pytest is missing is this
param
fixture that is not a real fixture as does not run any code, but is just a parameter broadcast entity that is different from parametrizing at the individual fixture/test level.Another example where this would be useful, with some API suggestions:
This feature was discussed in
TvoroG/pytest-lazy-fixture#25
#349 (comment)
I decided to open a new feature request because I believe it is a different use case/implementation than #349, although they might be related. The difference is that we don't need to worry about this that @nicoddemus mentioned:
Because we don't need to run any code to have all the parameters in place at collection time.
The text was updated successfully, but these errors were encountered: