You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Question: How to conditionally skip a generated test case #211
I have a test case function that's using the @parametrize decorator:
`
@parametrize(name=(HelperUtil.get_all_widgets()))
def case_widget(self, name):
return name
`
Then on the test function I have @parametrize_with_cases:
`
@parametrize_with_cases('val', cases=MyClassName)
def test_function(val):
`
This is working perfectly & processing the dozen odd values that get returned from @parametrize.
However, I'd like the test function that uses this to skip certain "name" values (eg skip if name in ['fred', 'harry', 'mick']
Based on your doco, I think the @parametrize_with_cases(filter=) option using regex can probably do this.
Can this be achieved with filters & if so what's the format of id's that get returned from @parametrize?
The first 3 test nodes use the case widget while the last one uses case foo.
Your question is about selecting bothfoo and some parametrized versions of widget, for example not widget "bob".
Filtering cases: KO
Unfortunately, filtering cases (using filters, tags, globs as described in here) applies solely on the cases directly collected by @parametrize_with_cases. So you can use it to select widget + foo, or only widget, or only foo, or none of them ; however if widget is selected, all of its versions (all of joe, bob and alice) will be selected. So it does not provide a solution to your need.
Inspecting current_cases: half of the solution
We can use the new current_cases fixture to see which cases are used by the current test node:
joe
('widget', <function MyClassName.case_widget at 0x000001FE3878CEE0>)
bob
('widget', <function MyClassName.case_widget at 0x000001FE3878CEE0>)
alice
('widget', <function MyClassName.case_widget at 0x000001FE3878CEE0>)
foo
('foo', <function MyClassName.case_foo at 0x000001DD74756E50>)
(note: while writing this I found issue #212 so if you do not have the exact same output you'll need to update to version 3.5.2)
Unfortunately this does not fully answer the question, since this fixture only tells you if widget or foo is used, not the parameter of widget. At least it provides half of the response by helping you to detect that widget is active.
Inspecting request: the solution
request is the pytest fixture providing all information about the current test node.
There are two ways that you can use it to solve your problem:
request.node.name provides you with the current node name as a string. You can therefore write:
@parametrize_with_cases('val', cases=MyClassName)deftest_function(val, request):
print(val)
ifrequest.node.name=='test_function[widget-name=joe]':
pytest.skip("joe is skipped !")
...
request.node.callspec.params is a dictionary that contains all parameter values set for the test, including parametrized fixtures. You can use it to get the parameter value of the widget case fixture that is generated behind the scenes:
@parametrize_with_cases('val', cases=MyClassName)deftest_function(val, request, current_cases):
print(val)
# get the current casecase_id, case_func=current_cases['val']
# skip if the case is widget and its param is "joe"ifcase_funcisMyClassName.case_widget:
ifrequest.node.callspec.params['widget'].argvalues[0] =="joe":
pytest.skip("joe is skipped !")
...
As you can see, this is a bit dirty but at least that's two workarounds for you.
In the future we may wish to modify the current_cases fixture so that each entry is a tuple containing 3 things instead of two: (case_id, case_func, case_param or None)
In the short term I've gone with the option of evaluating each case in the test function & skipping if not appropriate.
It works but is a little cludgy.
I guess the better longer term option is a custom function to filter the results currently being parametrized.
Hi @wonboyn , just for information: #214 has now been fixed in 3.6.0 so you can now solve your problem easily with the current_cases fixture alone:
@parametrize_with_cases('val', cases=MyClassName)deftest_function(val, current_cases):
print(val)
# get the current case and its parametersval_id, val_func, val_params=current_cases['val']
# skip if the case is widget and its param is "joe"ifval_funcisMyClassName.case_widgetandval_params["name"] =="joe":
pytest.skip("joe is skipped !")
...
Activity
smarie commentedon May 21, 2021
Thanks for this question @wonboyn
We'll need a complete reproducible example to discuss. Let's use this one:
This generates 4 test nodes:
The first 3 test nodes use the case
widgetwhile the last one uses casefoo.Your question is about selecting both
fooand some parametrized versions ofwidget, for examplenot widget "bob".Filtering cases: KO
Unfortunately, filtering cases (using filters, tags, globs as described in here) applies solely on the cases directly collected by
@parametrize_with_cases. So you can use it to selectwidget+foo, or onlywidget, or onlyfoo, or none of them ; however ifwidgetis selected, all of its versions (all of joe, bob and alice) will be selected. So it does not provide a solution to your need.Inspecting
current_cases: half of the solutionWe can use the new
current_casesfixture to see which cases are used by the current test node:Yields
(note: while writing this I found issue #212 so if you do not have the exact same output you'll need to update to version 3.5.2)
Unfortunately this does not fully answer the question, since this fixture only tells you if
widgetorfoois used, not the parameter ofwidget. At least it provides half of the response by helping you to detect thatwidgetis active.Inspecting
request: the solutionrequestis the pytest fixture providing all information about the current test node.There are two ways that you can use it to solve your problem:
request.node.nameprovides you with the current node name as a string. You can therefore write:request.node.callspec.paramsis a dictionary that contains all parameter values set for the test, including parametrized fixtures. You can use it to get the parameter value of thewidgetcase fixture that is generated behind the scenes:As you can see, this is a bit dirty but at least that's two workarounds for you.
In the future we may wish to modify the
current_casesfixture so that each entry is a tuple containing 3 things instead of two:(case_id, case_func, case_param or None)What do you think ?
Added a test for workaround in issue #211 + minor docstring edit + ch…
wonboyn commentedon May 25, 2021
Thanks for getting back to me.
In the short term I've gone with the option of evaluating each case in the test function & skipping if not appropriate.
It works but is a little cludgy.
I guess the better longer term option is a custom function to filter the results currently being parametrized.
smarie commentedon May 27, 2021
Thanks @wonboyn for the feedback!
smarie commentedon May 31, 2021
Hi @wonboyn , just for information: #214 has now been fixed in 3.6.0 so you can now solve your problem easily with the
current_casesfixture alone:Let me know if this works ok for you