Skip to content

"Empty id" mechanism in callspec #8155

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

Open
smarie opened this issue Dec 16, 2020 · 4 comments
Open

"Empty id" mechanism in callspec #8155

smarie opened this issue Dec 16, 2020 · 4 comments
Labels
type: proposal proposal for a new feature, often to gather opinions or design the API around the new feature

Comments

@smarie
Copy link
Contributor

smarie commented Dec 16, 2020

Hi dear pytest maintainers,

I noticed that starting in pytest 5.4.0, CallSpec2.id does not automatically filter out ids that are empty strings from the ids list. So if in the ids list there is ['a', '', 'b'] in old versions that would lead to id 'a-b' and now it leads to 'a--b'. I understand the rationale: pytest should not hide anything from users, so if there is an empty string id somewhere, it should appear.

Unfortunately I was relying on this undocumented mechanism in pytest-cases, because there is a specific situation with fixture unions induced by the new @parametrize, in which I wish to remove a useless piece of id from a callspec. I found an ugly workaround: to use a very long and unique string constant as a marker for "id to remove" and then have a specific cleaning hook in the plugin removing such constants from callspec ids lists.

I was wondering if there could be a better way for the future, baked in the pytest API. For example we could introduce an explicit pytest.NO_ID constant that would be filtered out in CallSpec2.id.

What do you think ? I can propose a PR if needed

@RonnyPfannschmidt
Copy link
Member

abd5fc8 from #6607 fixing #6597

i believe the union ids should be as a union parametrize call with explicit ids, im against a NO_ID

@RonnyPfannschmidt RonnyPfannschmidt added type: proposal proposal for a new feature, often to gather opinions or design the API around the new feature type: question general question, might be closed after 2 weeks of inactivity labels Dec 16, 2020
@smarie
Copy link
Contributor Author

smarie commented Dec 16, 2020

Thanks @RonnyPfannschmidt ! Yes I totally agree with you for fixture_union in general.

However the need arises with a parametrize containing fixture references:

from pytest_cases import parametrize, fixture, fixture_ref

@fixture
@parametrize("o", [1, 2])
def b(o):
    pass

@parametrize("a", [0, 1, 2, fixture_ref(b)])
def test_foo(a):
    pass

In that example, you probably agree that a good list of id would be:

test_blah.py::test_foo[0] PASSED                                         [ 20%]
test_blah.py::test_foo[1] PASSED                                         [ 40%]
test_blah.py::test_foo[2] PASSED                                         [ 60%]
test_blah.py::test_foo[b-1] PASSED                                       [ 80%]
test_blah.py::test_foo[b-2] PASSED                                       [100%]

However, behind the scenes, I do a little optimization so I create a fixture_ref for the first three parameters instead of creating a fixture for each of them. You can see it with the idstyle="explicit":

from pytest_cases import parametrize, fixture, fixture_ref

@fixture
@parametrize("o", [1, 2])
def b(o):
    pass

@parametrize("a", [0, 1, 2, fixture_ref(b)], idstyle="explicit")
def test_foo(a):
    pass

yields

test_blah.py::test_foo[a\P0:3-0] PASSED                                  [ 20%]
test_blah.py::test_foo[a\P0:3-1] PASSED                                  [ 40%]
test_blah.py::test_foo[a\P0:3-2] PASSED                                  [ 60%]
test_blah.py::test_foo[a\b-1] PASSED                                     [ 80%]
test_blah.py::test_foo[a\b-2] PASSED                                     [100%]

You can see that there are two hidden parameter controling the fixture union alternative "branch 1 = params 0:3" or "branch 2 = the fixture reference". With this id style we see explicit test ids a/P0:3 and a/b (supposed to be a slash but changed in the console, see #8157 )

So back to the ids of the first example above: in order to make them simple and straightforward, I need the "union alternative" parameter to completely disappear, not even remaining as a single dash. The best I can do without hack is:

test_blah.py::test_foo[-0] PASSED                                         [ 20%]
test_blah.py::test_foo[-1] PASSED                                         [ 40%]
test_blah.py::test_foo[-2] PASSED                                         [ 60%]
test_blah.py::test_foo[b-1] PASSED                                       [ 80%]
test_blah.py::test_foo[b-2] PASSED                                       [100%]

So I had to hack to remove the useless dash. This is where a NO_ID helper would help.

(Note: the above behaviour is in pytest-cases 3.0.0, about to be released)

@smarie
Copy link
Contributor Author

smarie commented Dec 16, 2020

For reference: the discussion about various styles of ids: smarie/python-pytest-cases#154 (comment)

@RonnyPfannschmidt
Copy link
Member

That seems to me like the full parameterset with explicit ids would have to be generated in pytest-cases to support reasonably complete I'd control

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: proposal proposal for a new feature, often to gather opinions or design the API around the new feature
Projects
None yet
Development

No branches or pull requests

3 participants