@@ -259,6 +259,18 @@ def get_parametrize_signature():
259259
260260
261261# ---------- test ids utils ---------
262+ def combine_ids (paramid_tuples ):
263+ """
264+ Receives a list of tuples containing ids for each parameterset.
265+ Returns the final ids, that are obtained by joining the various param ids by '-' for each test node
266+
267+ :param paramid_tuples:
268+ :return:
269+ """
270+ #
271+ return ['-' .join (pid for pid in testid ) for testid in paramid_tuples ]
272+
273+
262274def get_test_ids_from_param_values (param_names ,
263275 param_values ,
264276 ):
@@ -285,43 +297,81 @@ def get_test_ids_from_param_values(param_names,
285297
286298
287299# ---- ParameterSet api ---
288- def extract_parameterset_info ( pnames , pmark ):
300+ def analyze_parameter_set ( pmark = None , argnames = None , argvalues = None , ids = None ):
289301 """
302+ analyzes a parameter set passed either as a pmark or as distinct
303+ (argnames, argvalues, ids) to extract/construct the various ids, marks, and
304+ values
290305
291- :param pnames: the names in this parameterset
292- :param pmark: the parametrization mark (a _ParametrizationMark)
306+ :return: ids, marks, values
307+ """
308+ if pmark is not None :
309+ if any (a is not None for a in (argnames , argvalues , ids )):
310+ raise ValueError ("Either provide a pmark OR the details" )
311+ argnames = pmark .param_names
312+ argvalues = pmark .param_values
313+ ids = pmark .param_ids
314+
315+ # extract all parameters that have a specific configuration (pytest.param())
316+ custom_pids , p_marks , p_values = extract_parameterset_info (argnames , argvalues )
317+
318+ # Create the proper id for each test
319+ if ids is not None :
320+ # overridden at global pytest.mark.parametrize level - this takes precedence.
321+ try : # an explicit list of ids ?
322+ p_ids = list (ids )
323+ except TypeError : # a callable to apply on the values
324+ p_ids = list (ids (v ) for v in p_values )
325+ else :
326+ # default: values-based
327+ p_ids = get_test_ids_from_param_values (argnames , p_values )
328+
329+ # Finally, local pytest.param takes precedence over everything else
330+ for i , _id in enumerate (custom_pids ):
331+ if _id is not None :
332+ p_ids [i ] = _id
333+
334+ return p_ids , p_marks , p_values
335+
336+
337+ def extract_parameterset_info (argnames , argvalues ):
338+ """
339+
340+ :param argnames: the names in this parameterset
341+ :param argvalues: the values in this parameterset
293342 :return:
294343 """
295- _pids = []
296- _pmarks = []
297- _pvalues = []
298- for v in pmark . param_values :
344+ pids = []
345+ pmarks = []
346+ pvalues = []
347+ for v in argvalues :
299348 if is_marked_parameter_value (v ):
300349 # --id
301350 id = get_marked_parameter_id (v )
302- _pids .append (id )
351+ pids .append (id )
303352 # --marks
304353 marks = get_marked_parameter_marks (v )
305- _pmarks .append (marks ) # note: there might be several
354+ pmarks .append (marks ) # note: there might be several
306355 # --value(a tuple if this is a tuple parameter)
307356 vals = get_marked_parameter_values (v )
308- if len (vals ) != len (pnames ):
357+ if len (vals ) != len (argnames ):
309358 raise ValueError ("Internal error - unsupported pytest parametrization+mark combination. Please "
310359 "report this issue" )
311360 if len (vals ) == 1 :
312- _pvalues .append (vals [0 ])
361+ pvalues .append (vals [0 ])
313362 else :
314- _pvalues .append (vals )
363+ pvalues .append (vals )
315364 else :
316- _pids .append (None )
317- _pmarks .append (None )
318- _pvalues .append (v )
365+ pids .append (None )
366+ pmarks .append (None )
367+ pvalues .append (v )
319368
320- return _pids , _pmarks , _pvalues
369+ return pids , pmarks , pvalues
321370
322371
323372try : # pytest 3.x+
324373 from _pytest .mark import ParameterSet
374+
325375 def is_marked_parameter_value (v ):
326376 return isinstance (v , ParameterSet )
327377
0 commit comments