refactor(test): Update test parameterization

ref: #733 #730 #729
This commit is contained in:
2025-05-01 01:16:57 +09:30
parent 927776b9a7
commit 64757826da
5 changed files with 576 additions and 121 deletions

View File

@ -16,24 +16,48 @@ from app.tests.common import DoesNotExist
class APIFieldsTestCases:
api_fields_common = {
'id': int,
'display_name': str,
'_urls': dict,
'_urls._self': str,
'_urls.notes': str
'id': {
'expected': int
},
'display_name': {
'expected': str
},
'_urls': {
'expected': dict
},
'_urls._self': {
'expected': str
},
'_urls.notes': {
'expected': str
},
}
api_fields_model = {
'model_notes': str,
'created': str,
'modified': str
'model_notes': {
'expected': str
},
'created': {
'expected': str
},
'modified': {
'expected': str
},
}
api_fields_tenancy = {
'organization': dict,
'organization.id': int,
'organization.display_name': str,
'organization.url': Hyperlink,
'organization': {
'expected': dict
},
'organization.id': {
'expected': int
},
'organization.display_name': {
'expected': str
},
'organization.url': {
'expected': Hyperlink
},
}
parametrized_test_data = {
@ -156,12 +180,15 @@ class APIFieldsTestCases:
pass
def test_api_field_exists(self, recursearray, test_name, test_value, expected):
def test_api_field_exists(self, recursearray, parameterized, param_key_test_data,
param_value,
param_expected
):
"""Test for existance of API Field"""
api_data = recursearray(self.api_data, test_value)
api_data = recursearray(self.api_data, param_value)
if expected is DoesNotExist:
if param_expected is DoesNotExist:
assert api_data['key'] not in api_data['obj']
@ -171,18 +198,21 @@ class APIFieldsTestCases:
def test_api_field_type(self, recursearray, test_name, test_value, expected):
def test_api_field_type(self, recursearray, parameterized, param_key_test_data,
param_value,
param_expected
):
"""Test for type for API Field"""
api_data = recursearray(self.api_data, test_value)
api_data = recursearray(self.api_data, param_value)
if expected is DoesNotExist:
if param_expected is DoesNotExist:
assert api_data['key'] not in api_data['obj']
else:
assert type( api_data['value'] ) is expected
assert type( api_data['value'] ) is param_expected

View File

@ -41,11 +41,48 @@ def enable_db_access_for_all_tests(db): # pylint: disable=W0613:unused-argume
def pytest_generate_tests(metafunc):
# test_no_value = {"test_name", "test_value", "expected"} <= set(metafunc.fixturenames)
arg_values:list = None
# test_value = {"test_name", "test_value", "return_value", "expected"} <= set(metafunc.fixturenames)
fixture_parameters: list = []
parameterized_test = False
parameterized_key: str = None
if {'parameterized'} <= set(metafunc.fixturenames):
all_fixture_parameters = metafunc.fixturenames
fixture_parameters += ['parameterized']
for i in range(0, len(metafunc.fixturenames)):
if (
str(all_fixture_parameters[i]).startswith('param_')
and not str(all_fixture_parameters[i]).startswith('param_key_')
):
fixture_parameters += [ all_fixture_parameters[i] ]
elif str(all_fixture_parameters[i]).startswith('param_key_'):
parameterized_key = str( all_fixture_parameters[i] ).replace('param_key_', '')
if len(fixture_parameters) == 1:
fixture_parameters += [ all_fixture_parameters[i] ]
else:
fixture_parameters[1] = all_fixture_parameters[i]
parameterized_test = len(fixture_parameters) > 0
if parameterized_test:
if {"test_name", "test_value", "expected"} <= set(metafunc.fixturenames):
values = {}
@ -55,26 +92,129 @@ def pytest_generate_tests(metafunc):
for base in reversed(cls.__mro__):
base_values = getattr(base, "parametrized_test_data", [])
base_values = getattr(base, 'parametrized_' + parameterized_key, None)
if isinstance(base_values, dict):
if not isinstance(base_values, dict):
continue
if len(values) == 0 and len(base_values) > 0:
values.update(base_values)
continue
for key, value in values.items():
if(
type(value) is not dict
or key not in base_values
):
continue
if key not in values:
values.update({
key: base_values[key]
})
else:
values[key].update( base_values[key] )
for key, value in base_values.items():
if key not in values:
values.update({
key: base_values[key]
})
if values:
metafunc.parametrize(
argnames = (
"test_name", "test_value", "expected"
),
argvalues = [
(field, field, expected) for field, expected in values.items()
],
ids = [
str( field.replace('.', '_') + '_' + getattr(expected, '__name__', 'None').lower() ) for field, expected in values.items()
],
)
ids = []
arg_values:list = []
for item in values.items():
ids_name = item[0]
item_values:tuple = ()
length = len(item)
is_key_value: bool = True
if type(item[1]) is not dict:
continue
item_values += ( None, None, item[0])
for key in fixture_parameters:
if key in [ fixture_parameters[0], fixture_parameters[1], fixture_parameters[2], ]:
# these values are already defined in `item_values`
# fixture_parameters[0] = parameterized.
# fixture_parameters[1] = param_key
# fixture_parameters[2] = the dict name
continue
if(
str(key).startswith('param_')
and not str(key).startswith('param_key_')
):
key = str(key).replace('param_', '')
if (
type(item[1]) is not dict
or item[1].get(key, 'key-does_not-exist') == 'key-does_not-exist'
):
item_values = ()
continue
if key in item[1]:
item_values += ( item[1][key], )
if type(item[1][key]) is type:
ids_name += '_' + getattr(item[1][key], '__name__', 'None').lower()
else:
ids_name += '_' + str(item[1][key]).lower()
if(
len(item_values) > 0
and len(fixture_parameters) == len(item_values)
):
arg_values += [ item_values ]
ids += [ ids_name, ]
if len(arg_values) > 0:
metafunc.parametrize(
argnames = [
*fixture_parameters
],
argvalues = arg_values,
ids = ids,
)

View File

@ -114,93 +114,259 @@ class APITestCases(
parametrized_test_data = {
'model_notes': DoesNotExist,
'_urls.notes': DoesNotExist,
'external_system': int,
'external_ref': int,
'parent_ticket': dict,
'parent_ticket.id': int,
'parent_ticket.display_name': str,
'parent_ticket.url': str,
'ticket_type': str,
'status': int,
'status_badge': dict,
'status_badge.icon': dict,
'status_badge.icon.name': str,
'status_badge.icon.style': str,
'status_badge.text': str,
'status_badge.text_style': str,
'status_badge.url': type(None),
'category': dict,
'category.id': int,
'category.display_name': str,
'category.url': Hyperlink,
'title': str,
'description': str,
'ticket_duration': int,
'ticket_estimation': int,
'project': dict,
'project.id': int,
'project.display_name': str,
'project.url': Hyperlink,
'milestone': dict,
'milestone.id': int,
'milestone.display_name': str,
'milestone.url': str,
'urgency': int,
'urgency_badge': dict,
'urgency_badge.icon': dict,
'urgency_badge.icon.name': str,
'urgency_badge.icon.style': str,
'urgency_badge.text': str,
'urgency_badge.text_style': str,
'urgency_badge.url': type(None),
'impact': int,
'impact_badge': dict,
'impact_badge.icon': dict,
'impact_badge.icon.name': str,
'impact_badge.icon.style': str,
'impact_badge.text': str,
'impact_badge.text_style': str,
'impact_badge.url': type(None),
'priority': int,
'priority_badge': dict,
'priority_badge.icon': dict,
'priority_badge.icon.name': str,
'priority_badge.icon.style': str,
'priority_badge.text': str,
'priority_badge.text_style': str,
'priority_badge.url': type(None),
'opened_by': dict,
'opened_by.id': int,
'opened_by.display_name': str,
'opened_by.first_name': str,
'opened_by.last_name': str,
'opened_by.username': str,
'opened_by.username': str,
'opened_by.is_active': bool,
'opened_by.url': Hyperlink,
'model_notes': {
'expected': DoesNotExist
},
'_urls.notes': {
'expected': DoesNotExist
},
'external_system': {
'expected': int
},
'external_ref': {
'expected': int
},
'parent_ticket': {
'expected': dict
},
'parent_ticket.id': {
'expected': int
},
'parent_ticket.display_name': {
'expected': str
},
'parent_ticket.url': {
'expected': str
},
'ticket_type': {
'expected': str
},
'status': {
'expected': int
},
'status_badge': {
'expected': dict
},
'status_badge.icon': {
'expected': dict
},
'status_badge.icon.name': {
'expected': str
},
'status_badge.icon.style': {
'expected': str
},
'status_badge.text': {
'expected': str
},
'status_badge.text_style': {
'expected': str
},
'status_badge.url': {
'expected': type(None)
},
'category': {
'expected': dict
},
'category.id': {
'expected': int
},
'category.display_name': {
'expected': str
},
'category.url': {
'expected': Hyperlink
},
'title': {
'expected': str
},
'description': {
'expected': str
},
'ticket_duration': {
'expected': int
},
'ticket_estimation': {
'expected': int
},
'project': {
'expected': dict
},
'project.id': {
'expected': int
},
'project.display_name': {
'expected': str
},
'project.url': {
'expected': Hyperlink
},
'milestone': {
'expected': dict
},
'milestone.id': {
'expected': int
},
'milestone.display_name': {
'expected': str
},
'milestone.url': {
'expected': str
},
'urgency': {
'expected': int
},
'urgency_badge': {
'expected': dict
},
'urgency_badge.icon': {
'expected': dict
},
'urgency_badge.icon.name': {
'expected': str
},
'urgency_badge.icon.style': {
'expected': str
},
'urgency_badge.text': {
'expected': str
},
'urgency_badge.text_style': {
'expected': str
},
'urgency_badge.url': {
'expected': type(None)
},
'impact': {
'expected': int
},
'impact_badge': {
'expected': dict
},
'impact_badge.icon': {
'expected': dict
},
'impact_badge.icon.name': {
'expected': str
},
'impact_badge.icon.style': {
'expected': str
},
'impact_badge.text': {
'expected': str
},
'impact_badge.text_style': {
'expected': str
},
'impact_badge.url': {
'expected': type(None)
},
'priority': {
'expected': int
},
'priority_badge': {
'expected': dict
},
'priority_badge.icon': {
'expected': dict
},
'priority_badge.icon.name': {
'expected': str
},
'priority_badge.icon.style': {
'expected': str
},
'priority_badge.text': {
'expected': str
},
'priority_badge.text_style': {
'expected': str
},
'priority_badge.url': {
'expected': type(None)
},
'opened_by': {
'expected': dict
},
'opened_by.id': {
'expected': int
},
'opened_by.display_name': {
'expected': str
},
'opened_by.first_name': {
'expected': str
},
'opened_by.last_name': {
'expected': str
},
'opened_by.username': {
'expected': str
},
'opened_by.username': {
'expected': str
},
'opened_by.is_active': {
'expected': bool
},
'opened_by.url': {
'expected': Hyperlink
},
'subscribed_to': list,
'subscribed_to.0.id': int,
'subscribed_to.0.display_name': str,
'subscribed_to.0.url': str,
'subscribed_to': {
'expected': list
},
'subscribed_to.0.id': {
'expected': int
},
'subscribed_to.0.display_name': {
'expected': str
},
'subscribed_to.0.url': {
'expected': str
},
'assigned_to': list,
'assigned_to.0.id': int,
'assigned_to.0.display_name': str,
'assigned_to.0.url': str,
'assigned_to': {
'expected': list
},
'assigned_to.0.id': {
'expected': int
},
'assigned_to.0.display_name': {
'expected': str
},
'assigned_to.0.url': {
'expected': str
},
'planned_start_date': str,
'planned_finish_date': str,
'real_start_date': str,
'real_finish_date': str,
'planned_start_date': {
'expected': str
},
'planned_finish_date': {
'expected': str
},
'real_start_date': {
'expected': str
},
'real_finish_date': {
'expected': str
},
'is_deleted': bool,
'is_solved': bool,
'date_solved': str,
'is_closed': bool,
'date_closed': str,
'is_deleted': {
'expected': bool
},
'is_solved': {
'expected': bool
},
'date_solved': {
'expected': str
},
'is_closed': {
'expected': bool
},
'date_closed': {
'expected': str
},
}

View File

@ -9,9 +9,12 @@ class TicketSLMAPITestCases(
):
parametrized_test_data = {
'tto': int,
'ttr': int,
'tto': {
'expected': int
},
'ttr': {
'expected': int
}
}
kwargs_create_item: dict = {