From 6a0cddb8a62da3ab6068fe2c1fca240c03c9d4ab Mon Sep 17 00:00:00 2001 From: yuxuan-ms Date: Mon, 2 Dec 2024 16:12:47 +0800 Subject: [PATCH] Change the default name function of parameters testcase. --- doc/newsfragments/3160_changed.case_name.rst | 1 + testplan/testing/multitest/parametrization.py | 41 ++++++++++++++---- testplan/testing/multitest/suite.py | 4 +- .../testing/multitest/test_parametrization.py | 42 +++++++++---------- .../testplan/testing/test_tagging.py | 16 +++---- 5 files changed, 66 insertions(+), 38 deletions(-) create mode 100755 doc/newsfragments/3160_changed.case_name.rst diff --git a/doc/newsfragments/3160_changed.case_name.rst b/doc/newsfragments/3160_changed.case_name.rst new file mode 100755 index 000000000..1be5f1a32 --- /dev/null +++ b/doc/newsfragments/3160_changed.case_name.rst @@ -0,0 +1 @@ +Limit the length of parameterization testcase name to 255 characters. If the name length exceeds 255 characters, index-suffixed names (e.g., {func_name[:240]} 1, {func_name[:240]} 2) will be used. \ No newline at end of file diff --git a/testplan/testing/multitest/parametrization.py b/testplan/testing/multitest/parametrization.py index 528e8de93..2e2adbcdb 100644 --- a/testplan/testing/multitest/parametrization.py +++ b/testplan/testing/multitest/parametrization.py @@ -9,6 +9,7 @@ from testplan.common.utils import callable as callable_utils from testplan.common.utils import convert, interface from testplan.testing import tagging +from typing import Callable, Optional # Although any string will be processed as normal, it's a good # approach to warn the user if the generated method name is not a @@ -206,8 +207,11 @@ def _generated(self, env, result): ) # Users request the feature that when `name_func` set to `None`, # then simply append integer suffixes to the names of testcases - _generated.name = ( - name_func(name, kwargs) if name_func is not None else f"{name} {idx}" + _generated.name = _parametrization_report_name_func_wrapper( + name_func=name_func, + name=name, + kwargs=kwargs, + index=idx, ) if hasattr(function, "__xfail__"): @@ -267,7 +271,7 @@ def _check_tag_func(tag_func): ) -def _parametrization_name_func_wrapper(func_name, kwargs): +def _parametrization_name_func_wrapper(func_name: str, kwargs: dict): """ Make sure that name generation doesn't end up with invalid / unreadable attribute names/types etc. @@ -291,6 +295,31 @@ def _parametrization_name_func_wrapper(func_name, kwargs): return generated_name +def _parametrization_report_name_func_wrapper( + name_func: Optional[Callable], name: str, kwargs: dict, index: int +): + """ + Make sure that generated name is not too long, + if it is, then use index suffixed names e.g. "{func_name} 1", "{func_name} 2", will be used. + """ + if name_func: + generated_name = name_func(name, kwargs) + if not isinstance(generated_name, str): + raise ValueError( + "The return value of name_func must be a string, " + f"it is of type: {type(generated_name)}, value: {generated_name}" + ) + if len(generated_name) <= MAX_METHOD_NAME_LENGTH: + return generated_name + else: + warnings.warn( + f"The name name_func returned ({generated_name}) is too long, using index suffixed names." + ) + + generated_name = f"{name[:MAX_METHOD_NAME_LENGTH - 10]} {index}" + return generated_name + + def parametrization_name_func(func_name, kwargs): """ Method name generator for parametrized testcases. @@ -321,7 +350,7 @@ def default_name_func(func_name, kwargs): >>> import collections >>> default_name_func('Test Method', collections.OrderedDict(('foo', 5), ('bar', 10))) - 'Test Method {foo:5, bar:10}' + 'Test Method ' :param func_name: Name of the parametrization target function. :type func_name: ``str`` @@ -334,9 +363,7 @@ def default_name_func(func_name, kwargs): """ arg_strings = ["{arg}={{{arg}}}".format(arg=arg) for arg in kwargs] template = "{func_name} <" + ", ".join(arg_strings) + ">" - return template.format( - func_name=func_name, **{k: repr(v) for k, v in kwargs.items()} - ) + return template.format(func_name=func_name, **kwargs) def generate_functions( diff --git a/testplan/testing/multitest/suite.py b/testplan/testing/multitest/suite.py index 9d03ee7c5..ea9115511 100644 --- a/testplan/testing/multitest/suite.py +++ b/testplan/testing/multitest/suite.py @@ -581,9 +581,9 @@ def _validate_testcase(func): if len(func.name) > defaults.MAX_TEST_NAME_LENGTH: warnings.warn( - 'Name defined for testcase "{}" is too long,' + f'Name defined for testcase "{func.name}" is too long,' ' consider customizing testcase name with argument "name_func"' - " in @testcase decorator.".format(func.__name__) + " in @testcase decorator." ) diff --git a/tests/functional/testplan/testing/multitest/test_parametrization.py b/tests/functional/testplan/testing/multitest/test_parametrization.py index 4ce973faf..e87839909 100644 --- a/tests/functional/testplan/testing/multitest/test_parametrization.py +++ b/tests/functional/testplan/testing/multitest/test_parametrization.py @@ -143,19 +143,19 @@ def test_sample(self, env, result, a, b): category=ReportCategories.PARAMETRIZATION, entries=[ TestCaseReport( - name="test_sample ", + name="test_sample ", entries=[{"type": "IsTrue", "description": "1 - alpha"}], ), TestCaseReport( - name="test_sample ", + name="test_sample ", entries=[{"type": "IsTrue", "description": "1 - beta"}], ), TestCaseReport( - name="test_sample ", + name="test_sample ", entries=[{"type": "IsTrue", "description": "2 - alpha"}], ), TestCaseReport( - name="test_sample ", + name="test_sample ", entries=[{"type": "IsTrue", "description": "2 - beta"}], ), ], @@ -297,7 +297,7 @@ def sample(self, env, result, test__val): ( ( ("#@)$*@#%", "a-b"), - ["sample_test ", "sample_test "], + ["sample_test ", "sample_test "], ["sample_test__0", "sample_test__1"], "Should use original method name + index fallback if" " generated names are not valid Python attribute names.", @@ -305,8 +305,8 @@ def sample(self, env, result, test__val): ( ("a" * MAX_METHOD_NAME_LENGTH, "b" * MAX_METHOD_NAME_LENGTH), [ - "sample_test ".format("a" * MAX_METHOD_NAME_LENGTH), - "sample_test ".format("b" * MAX_METHOD_NAME_LENGTH), + "sample_test 0", + "sample_test 1", ], ["sample_test__0", "sample_test__1"], "Should use original method name + index fallback if" @@ -363,8 +363,8 @@ def sample_test(self, env, result, a, b): name="Sample Test", category=ReportCategories.PARAMETRIZATION, entries=[ - TestCaseReport(name="Sample Test "), - TestCaseReport(name="Sample Test "), + TestCaseReport(name="Sample Test "), + TestCaseReport(name="Sample Test "), ], ) @@ -599,13 +599,13 @@ def dummy_test(self, env, result, color): tags={"simple": {"alpha"}}, entries=[ TestCaseReport( - name="dummy_test ", tags={"color": {"red"}} + name="dummy_test ", tags={"color": {"red"}} ), TestCaseReport( - name="dummy_test ", tags={"color": {"blue"}} + name="dummy_test ", tags={"color": {"blue"}} ), TestCaseReport( - name="dummy_test ", tags={"color": {"green"}} + name="dummy_test ", tags={"color": {"green"}} ), ], ) @@ -652,9 +652,9 @@ def dummy_test_5(self, env, result, smell): name="dummy_test_1", category=ReportCategories.PARAMETRIZATION, entries=[ - TestCaseReport(name="dummy_test_1 "), - TestCaseReport(name="dummy_test_1 "), - TestCaseReport(name="dummy_test_1 "), + TestCaseReport(name="dummy_test_1 "), + TestCaseReport(name="dummy_test_1 "), + TestCaseReport(name="dummy_test_1 "), ], ), TestCaseReport(name="dummy_test_2"), @@ -662,9 +662,9 @@ def dummy_test_5(self, env, result, smell): name="dummy_test_3", category=ReportCategories.PARAMETRIZATION, entries=[ - TestCaseReport(name="dummy_test_3 "), - TestCaseReport(name="dummy_test_3 "), - TestCaseReport(name="dummy_test_3 "), + TestCaseReport(name="dummy_test_3 "), + TestCaseReport(name="dummy_test_3 "), + TestCaseReport(name="dummy_test_3 "), ], ), TestCaseReport(name="dummy_test_4"), @@ -672,9 +672,9 @@ def dummy_test_5(self, env, result, smell): name="dummy_test_5", category=ReportCategories.PARAMETRIZATION, entries=[ - TestCaseReport(name="dummy_test_5 "), - TestCaseReport(name="dummy_test_5 "), - TestCaseReport(name="dummy_test_5 "), + TestCaseReport(name="dummy_test_5 "), + TestCaseReport(name="dummy_test_5 "), + TestCaseReport(name="dummy_test_5 "), ], ), ] diff --git a/tests/functional/testplan/testing/test_tagging.py b/tests/functional/testplan/testing/test_tagging.py index 14f0c8926..77a03c225 100644 --- a/tests/functional/testplan/testing/test_tagging.py +++ b/tests/functional/testplan/testing/test_tagging.py @@ -94,11 +94,11 @@ def test_param_2(self, env, result, value): tags={"speed": {"slow"}}, entries=[ TestCaseReport( - name="test_param ", + name="test_param ", tags={"symbol": {"aaa"}}, ), TestCaseReport( - name="test_param ", + name="test_param ", tags={"symbol": {"bbb"}}, ), ], @@ -108,8 +108,8 @@ def test_param_2(self, env, result, value): category="parametrization", tags={"speed": {"fast"}}, entries=[ - TestCaseReport(name="test_param_2 "), - TestCaseReport(name="test_param_2 "), + TestCaseReport(name="test_param_2 "), + TestCaseReport(name="test_param_2 "), ], ), ], @@ -158,11 +158,11 @@ def test_param_2(self, env, result, value): tags={"speed": {"slow"}}, entries=[ TestCaseReport( - name="test_param ", + name="test_param ", tags={"symbol": {"aaa"}}, ), TestCaseReport( - name="test_param ", + name="test_param ", tags={"symbol": {"bbb"}}, ), ], @@ -172,8 +172,8 @@ def test_param_2(self, env, result, value): category="parametrization", tags={"speed": {"fast"}}, entries=[ - TestCaseReport(name="test_param_2 "), - TestCaseReport(name="test_param_2 "), + TestCaseReport(name="test_param_2 "), + TestCaseReport(name="test_param_2 "), ], ), ],