I have the following function:
def checking_remote_local_groups(data: List[dict], groups: List[dict]) -> List[dict]:
step = 'GET_GROUPS_TO_CHECK'
groups_to_check = []
local_groups = [x['group'] for x in data]
# Using set to get differences between local and AAD groups
local_groups_set = set(local_groups)
groups_set = set(x['name'] for x in groups)
# If local AAD groups set are not in AAD groups, raise an Error on the workflow.
if local_groups_set - groups_set:
# SyncException is implemented somewhere.
raise SyncException(
f'{local_groups_set - groups_set} local group is not an AAD group\nCreate it via speckle-infra terraform',
"We need to get in line, local and AAD groups. Additional {} group received from users.yaml".format(
local_groups_set - groups_set
),
step
)
# If remote groups set are not in local groups
if groups_set - local_groups_set:
# Just notify it to the user
warnings.warn(
f"""
{groups_set - local_groups_set} AAD group is not on users.yml as a local group
Please add it if needed
"""
)
# If remote groups are the same than local groups
elif local_groups_set == groups_set:
print("AAD and local groups are inline"
)
return groups_to_check
I want to check the behavior of the second if
section code (If remote groups set are not in local groups) by doing unittests using the assertWarns assertion, since I am triggering a warning in that case. So I have:
class MyTestCase(unittest.TestCase):
def test_warning_checking_remote_group_not_in_local_groups(self):
# local groups
data = [{'group': 'foobar'}, {'group': 'test'}]
# remote groups
groups = [{'name': 'foobar'}, {'name': 'test'}, {'name': 'missing'}]
self.assertWarns(
UserWarning,
checking_aad_local_groups(data, groups),
[{"name": "missing"}]
)
I got this output:
test_sync.py .F........... [100%]
=================================== FAILURES ===================================
______ GroupsTestCase.test_warning_checking_aad_group_not_in_local_groups ______
self = <test_sync.GroupsTestCase testMethod=test_warning_checking_remote_group_not_in_local_groups>
def test_warning_checking_remote_group_not_in_local_groups(self):
data = [{'group': 'foobar'}, {'group': 'test'}]
groups = [{'name': 'foobar'}, {'name': 'test'}, {'name': 'missing'}]
> self.assertWarns(
UserWarning,
checking_aad_local_groups(data, groups),
[{"name": "missing"}]
)
E TypeError: 'list' object is not callable
test_sync.py:158: TypeError
=============================== warnings summary ===============================
test_sync.py::GroupsTestCase::test_warning_checking_aad_group_not_in_local_groups
/home/runner/work/speckle-user-management/speckle-user-management/groups.py:31: UserWarning:
*********************** WARNING ... ***********************
{'missing'} AAD group is not on users.yml as a local group
Please add it if needed
*********************** WARNING ... ***********************
warnings.warn(
-- Docs: docs.pytest.org/en/latest/warnings.html
=========================== short test summary info ============================
FAILED test_sync.py::GroupsTestCase::test_warning_checking_remote_group_not_in_local_groups
I understand probably the list of dictionaries I am sending as a parameters are not accepted or are not available for the types of data assertWarns()
expect?
Despite that, the message I expected ({'missing'} AAD group is not on users.yml as a local group, Please add it if needed
) is shown, but I expect from this test pass.
What is the best way to use assertWarns()
.
If I use assertFalse, the test pass, although I am not sure if is the most specific/better assert I can use.
When you call assertWarns(UserWarning, checking_aad_local_groups(...))
then you are calling checking_aad_local_groups
and passing the result to assertWarns
. You want to give assertWarns
a callable so that it can wrap it in the warning detection code.
self.assertWarns(UserWarning, checking_aad_local_groups, (data, groups))
Alternatively, you can use it as a context manager
with self.assertWarns() as w:
checking_aad_local_groups(data, groups)