From e183ce1b3666bc509ee05104785f7aebbe6eded8 Mon Sep 17 00:00:00 2001 From: Yann poupon Date: Fri, 22 Nov 2024 14:27:44 +0100 Subject: [PATCH] fix: step report issue with TypeError --- src/pykiso/test_coordinator/test_case.py | 22 +++++ src/pykiso/test_result/assert_step_report.py | 28 ++++++ tests/test_assert_step_report.py | 91 ++++++++++++-------- 3 files changed, 105 insertions(+), 36 deletions(-) diff --git a/src/pykiso/test_coordinator/test_case.py b/src/pykiso/test_coordinator/test_case.py index 11181c9d..954e3bbc 100644 --- a/src/pykiso/test_coordinator/test_case.py +++ b/src/pykiso/test_coordinator/test_case.py @@ -25,6 +25,7 @@ import functools import logging import unittest +import warnings from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union import lxml @@ -128,6 +129,27 @@ def properties(self, value): def properties(self): del self._properties + # Overwrite the deprecate function to keep the signature for step report + @staticmethod + def _deprecate(original_func): + @functools.wraps(original_func) + def deprecated_func(*args, **kwargs): + warnings.warn("Please use {0} instead.".format(original_func.__name__), DeprecationWarning, 2) + return original_func(*args, **kwargs) + + return deprecated_func + + failUnlessEqual = assertEquals = _deprecate(unittest.TestCase.assertEqual) + failIfEqual = assertNotEquals = _deprecate(unittest.TestCase.assertNotEqual) + failUnlessAlmostEqual = assertAlmostEquals = _deprecate(unittest.TestCase.assertAlmostEqual) + failIfAlmostEqual = assertNotAlmostEquals = _deprecate(unittest.TestCase.assertNotAlmostEqual) + failUnless = assert_ = _deprecate(unittest.TestCase.assertTrue) + failUnlessRaises = _deprecate(unittest.TestCase.assertRaises) + failIf = _deprecate(unittest.TestCase.assertFalse) + assertRaisesRegexp = _deprecate(unittest.TestCase.assertRaisesRegex) + assertRegexpMatches = _deprecate(unittest.TestCase.assertRegex) + assertNotRegexpMatches = _deprecate(unittest.TestCase.assertNotRegex) + class RemoteTest(BasicTest): """Base test-cases for Message Protocol / TestApp usage.""" diff --git a/src/pykiso/test_result/assert_step_report.py b/src/pykiso/test_result/assert_step_report.py index 777b88f4..6717384f 100644 --- a/src/pykiso/test_result/assert_step_report.py +++ b/src/pykiso/test_result/assert_step_report.py @@ -70,6 +70,15 @@ # Jinja template location SCRIPT_PATH = str(Path(__file__).resolve().parent) REPORT_TEMPLATE = "templates/report_template.html.j2" +UNITTEST_DEPRECATED_FUNCTION_MAPPING: dict[str:str] = { + "assertEqual": "assertEquals", + "assertNotEqual": "assertNotEquals", + "assertAlmostEqual": "assertAlmostEquals", + "assertNotAlmostEqual": "assertNotAlmostEquals", + "assertRaisesRegex": "assertRaisesRegexp", + "assertRegex": "assertRegexpMatches", + "assertNotRegex": "assertNotRegexpMatches", +} @dataclass @@ -313,11 +322,17 @@ def func_wrapper(*args, **kwargs): return: The assertion method output if it exists. Otherwise, None """ global _FUNCTION_TO_APPLY + original_logic = False try: # Context currentframe = inspect.currentframe() f_back = currentframe.f_back + # Case where the assert is called in unittest so we don't want to add any logic + if f_back.f_globals["__name__"] == "unittest.case": + original_logic = True + return assert_method(*args, **kwargs) + test_name = determine_parent_test_function(f_back.f_code.co_name) test_case_inst: TestCase = assert_method.__self__ test_class_name = type(test_case_inst).__name__ @@ -352,12 +367,23 @@ def func_wrapper(*args, **kwargs): # 1.3. Get variable name found = False + deprecated_try = False while not found: try: var_name = _get_variable_name(f_back, assert_name) found = True except IndexError: f_back = f_back.f_back + except TypeError: + # replace assert name with depecrated function assert name + if not deprecated_try and assert_name in UNITTEST_DEPRECATED_FUNCTION_MAPPING.keys(): + deprecated_try = True + f_back = currentframe.f_back + assert_name = UNITTEST_DEPRECATED_FUNCTION_MAPPING[assert_name] + continue + log.error(f"Step report error: Variable name couldn't be find for {currentframe.f_back}") + var_name = "Variable name not found" + break # 1.4. Get Expected value expected = _get_expected(assert_name, arguments) @@ -377,6 +403,8 @@ def func_wrapper(*args, **kwargs): ) except Exception as e: + if original_logic: + raise e log.exception(f"Unable to update Step due to exception: {e}") # Run the assert method and mark the test as failed if the AssertionError is raised diff --git a/tests/test_assert_step_report.py b/tests/test_assert_step_report.py index b98d7ea3..24c3abda 100644 --- a/tests/test_assert_step_report.py +++ b/tests/test_assert_step_report.py @@ -27,9 +27,7 @@ def test_case(): tc.assertAlmostEqual = assert_step_report.assert_decorator(tc.assertAlmostEqual) # Add the step-report parameters - tc.step_report = assert_step_report.StepReportData( - header={}, message="", success=True, current_table=None - ) + tc.step_report = assert_step_report.StepReportData(header={}, message="", success=True, current_table=None) return tc @@ -53,9 +51,7 @@ def get_message_type(self): tc.assertEqual = assert_step_report.assert_decorator(tc.assertEqual) # Add the step-report parameters - tc.step_report = assert_step_report.StepReportData( - header={}, message="", success=True, current_table=None - ) + tc.step_report = assert_step_report.StepReportData(header={}, message="", success=True, current_table=None) return tc @@ -140,9 +136,9 @@ def test_assert_decorator_reraise(mocker, test_case): test_case.assertTrue(data_to_test, msg="Dummy message") assert ( - assert_step_report.ALL_STEP_REPORT["TestCase"]["test_list"][ - "test_assert_decorator_reraise" - ]["steps"][-1][-1]["succeed"] + assert_step_report.ALL_STEP_REPORT["TestCase"]["test_list"]["test_assert_decorator_reraise"]["steps"][-1][-1][ + "succeed" + ] == False ) step_result.assert_called_once_with( @@ -175,9 +171,7 @@ def test_assert_decorator_no_var_name(mocker, test_case): test_case.assertTrue(True) - step_result.assert_called_once_with( - "TestCase", "test_assert_decorator_no_var_name", "", "True", "True", True - ) + step_result.assert_called_once_with("TestCase", "test_assert_decorator_no_var_name", "", "True", "True", True) def test_assert_decorator_index_error(mocker, test_case): @@ -196,9 +190,7 @@ def test_assert_decorator_multi_input(mocker, test_case): data_to_test = 4.5 data_expected = 4.5 - test_case.assertAlmostEqual( - data_to_test, data_expected, delta=1, msg="Test the step report" - ) + test_case.assertAlmostEqual(data_to_test, data_expected, delta=1, msg="Test the step report") step_result.assert_called_once_with( "TestCase", @@ -216,9 +208,7 @@ def test_generate(mocker, test_result): assert_step_report.ALL_STEP_REPORT["TestClassName"]["time_result"] = OrderedDict() assert_step_report.ALL_STEP_REPORT["TestClassName"]["time_result"]["Start Time"] = 1 assert_step_report.ALL_STEP_REPORT["TestClassName"]["time_result"]["End Time"] = 2 - assert_step_report.ALL_STEP_REPORT["TestClassName"]["time_result"][ - "Elapsed Time" - ] = 1 + assert_step_report.ALL_STEP_REPORT["TestClassName"]["time_result"]["Elapsed Time"] = 1 jinja2.FileSystemLoader = mock_loader = mock.MagicMock() jinja2.Environment = mock_environment = mock.MagicMock() @@ -234,12 +224,10 @@ def test_generate(mocker, test_result): def test_add_step(): assert_step_report.ALL_STEP_REPORT["TestCase"] = OrderedDict() assert_step_report.ALL_STEP_REPORT["TestCase"]["test_list"] = OrderedDict() - assert_step_report.ALL_STEP_REPORT["TestCase"]["test_list"][ - "test_assert_step_report_multi_input" - ] = {} - steplist = assert_step_report.ALL_STEP_REPORT["TestCase"]["test_list"][ - "test_assert_step_report_multi_input" - ]["steps"] = [[]] + assert_step_report.ALL_STEP_REPORT["TestCase"]["test_list"]["test_assert_step_report_multi_input"] = {} + steplist = assert_step_report.ALL_STEP_REPORT["TestCase"]["test_list"]["test_assert_step_report_multi_input"][ + "steps" + ] = [[]] assert_step_report._add_step( "TestCase", @@ -333,13 +321,9 @@ def test_add_retry_information(mocker, result_test): } assert_step_report.ALL_STEP_REPORT = all_step_report_mock - assert_step_report.add_retry_information( - mock_test_case_class, result_test, retry_nb, max_try, ValueError - ) + assert_step_report.add_retry_information(mock_test_case_class, result_test, retry_nb, max_try, ValueError) - test_info = assert_step_report.ALL_STEP_REPORT[type(mock_test_case_class).__name__][ - "test_list" - ]["test_run"] + test_info = assert_step_report.ALL_STEP_REPORT[type(mock_test_case_class).__name__]["test_list"]["test_run"] assert test_info["steps"] == [ [{"succeed": False}, {"succeed": True}], [], @@ -351,10 +335,45 @@ def test_add_retry_information(mocker, result_test): assert test_info["max_try"] == max_try assert test_info["number_try"] == retry_nb + 1 - assert ( - assert_step_report.ALL_STEP_REPORT[type(mock_test_case_class).__name__][ - "succeed" - ] - == result_test - ) + assert assert_step_report.ALL_STEP_REPORT[type(mock_test_case_class).__name__]["succeed"] == result_test format_exec_mock.assert_called_once() + + +def test_assert_decorator_step_report_message_deprecated(mocker, remote_test_case): + step_result = mocker.patch("pykiso.test_result.assert_step_report._add_step") + remote_test_case.assertEquals = assert_step_report.assert_decorator(remote_test_case.assertEquals) + + var = "Test" + expected_var = "Test" + remote_test_case.assertEquals(var, expected_var, "not expected str") + + assert step_result.call_count == 1 + step_result.assert_called_once_with( + "RemoteTest", + "test_assert_decorator_step_report_message_deprecated", + "not expected str", + "var", + "Equals to Test", + "Test", + ) + + +def test_assert_decorator_step_report_assert_called_in_unittest(mocker, remote_test_case): + step_result = mocker.patch("pykiso.test_result.assert_step_report._add_step") + remote_test_case.assertEqual = assert_step_report.assert_decorator(remote_test_case.assertEqual) + remote_test_case.assertMultiLineEqual = assert_step_report.assert_decorator(remote_test_case.assertMultiLineEqual) + remote_test_case.assertIsInstance = assert_step_report.assert_decorator(remote_test_case.assertIsInstance) + + var = "Test" + expected_var = "Test" + remote_test_case.assertEqual(var, expected_var, "not expected str") + + assert step_result.call_count == 1 + step_result.assert_called_once_with( + "RemoteTest", + "test_assert_decorator_step_report_assert_called_in_unittest", + "not expected str", + "var", + "Equal to Test", + "Test", + )