You can use request.node.callspec.id
from the Request Fixture.
But take note that the value depends on whether the ids
function "generates a string representation to make part of the test ID". From pytest's docs on Different options for test IDs, the stringified version of the param is normally added to the test ID.
For example, if the ids
function generates an ID that does not include the stringified param or does not depend on anything else:
import random
def generate_random_id(param) -> str:
return f'{random.randint(1,100)}'
testdata = ['argA', 'argB']
@pytest.mark.parametrize('param', testdata, ids=generate_random_id)
def test_foo(param, request):
print(request.node.callspec.id)
Then you would get the generated ID as-is:
tests/test_a.py::test_foo[78] PASSED
tests/test_a.py::test_foo[10] PASSED
============================ PASSES =============================
_________________________ test_foo[78] __________________________
--------------------- Captured stdout call ----------------------
78
_________________________ test_foo[10] __________________________
--------------------- Captured stdout call ----------------------
10
If the ids
function includes the string representation of the param, then you would need some sort of delimiter to manually split the param and the test ID:
import random
def generate_random_id(param):
test_id = random.randint(1, 100)
return f'{param}-{test_id}'
testdata = ['argA', 'argB']
@pytest.mark.parametrize('param', testdata, ids=generate_random_id)
def test_foo(param, request):
param, test_id = request.node.callspec.id.split('-')
print(param)
print(test_id)
tests/test_a.py::test_foo[argA-43] PASSED
tests/test_a.py::test_foo[argB-37] PASSED
============================ PASSES =============================
_______________________ test_foo[argA-43] _______________________
--------------------- Captured stdout call ----------------------
argA
43
_______________________ test_foo[argB-37] _______________________
--------------------- Captured stdout call ----------------------
argB
37
If there are multiple params, then it becomes more complicated, since all the param + ids
combinations are concatenated together to create the full Test ID. You will need a separate delimiter different from -
:
import random
def generate_random_id(param):
test_id = random.randint(1, 100)
return f'{param}+{test_id}' # Use '+' to separate param+ID
testdata = [
('argA', 'argB'),
('argC', 'argD'),
]
@pytest.mark.parametrize('param1, param2', testdata, ids=generate_random_id)
def test_foo(param1, param2, request):
print(request.node.callspec.id)
params = request.node.callspec.id.split('-')
for a_param in params:
param, test_id = a_param.split('+')
print(param)
print(test_id)
tests/test_a.py::test_foo[argA+70-argB+25] PASSED
tests/test_a.py::test_foo[argC+97-argD+30] PASSED
===================================== PASSES =====================================
___________________________ test_foo[argA+70-argB+25] ____________________________
------------------------------ Captured stdout call ------------------------------
argA+70-argB+25
argA
70
argB
25
___________________________ test_foo[argC+97-argD+30] ____________________________
------------------------------ Captured stdout call ------------------------------
argC+97-argD+30
argC
97
argD
30