Ignoring AssertionError while setting a state or value

One of the earliest questions I expect to be raised here is how to handle instances where interaction with a component might result in the field not taking the requested state or value. This is of course expected when interacting with a disabled component, or when localization would alter the format of the supplied value.

The AssertionError raised in these scenarios is technically correct because the component failed to apply the interaction or value to the component, and you need to be made aware. That being said, the AssertionError will stop the execution of your test case.

So how do you avoid your test from stopping with a failure in these instances where you know the desired state will not be applied as expected?

In instances where a specific individual field is expected to fail, you should wrap the individual usage in a try/except block which ignores the exception in only this instance

(Simplified) Example for a Checkbox which is currently disabled:

self.page_object_a.navigate_to(self.page_object_b)
self.page_object_b.click_checkbox()  # Failure point due to AssertionError, as this checkbox is disabled based on user permissions
assert not self.page_object_b.image_is_visible()  # verifies checkbox binding has not activated image

Correct handling for individual instance:

self.page_object_a.navigate_to(self.page_object_b)
try:
    self.page_object_b.click_checkbox()
except AssertionError:
    pass  # ignore the AssertionError as you expect it to occur
assert not self.page_object_b.image_is_visible()

Note that this handling is NOT done at the Page level as other usages of this checkbox are expected to work; this try/except block would ignore other valid warnings if applied to all usages at the Page level.

Now, for instances where usages will always fail: Localization. One assumption our automated components do make is that you're using an en-US locale. We're sorry, but we have to gear our automation tools around our most likely use cases. As a result, Sessions which use locales which would modify the number format are going to encounter AssertionError failures any time they attempt to set a Numeric Entry Field. So what to do?

The best solution at this point in time is to provide your own wrapper which either ignores the AssertionError, or which waits on the expected text based on your locale.

Pseudo-code for a proprietary overwrite of our provided component:

import locale

from Components.PerspectiveComponents.Inputs.NumericEntryField import DirectNEF
from Helpers.IAExpectedConditions import IAExpectedConditions as IAec


class InternalDirectNEF(DirectNEF):
    def __init__(self, ... locale_in_use):
        DirectNEF.__init__(self, ...)
        locale.setlocale(locale.LC_ALL, locale_in_use)

    def set_text(self, text, release_focus, binding_wait_time):
        try:
            DirectNEF.set_text(text, release_focus, binding_wait_time)
        except AssertionError:
            # ignore return value here
            expected_localized_value. = '{0:n}'.format(text)
            self.wait_on_text_condition(text=expected_localized_value, condition=TextCondition.MATCHES)

This results in your own wrapper of our component, where the set_text function uses the same mechanism to set the text, but which will wait for the Direct Numeric Entry Field to display the localized value.

5 Likes