Use Custom Decorator with Run Keyword and Continue on Failure

I noticed that I have to wrap critical testing keywords with ‘Run Keyword and Continue on Failure.’ Our Robot suite leverages custom keywords in Python that get called and thought it would be clever to leverage the built-in library to wrap them ‘under the hood.’

Consider the test code below, …/lib/test.py:
from robot.libraries.BuiltIn import BuiltIn
from robot.api import logger
from functools import wraps
class test:

    ROBOT_LIBRARY_SCOPE = 'SUITE'
    ROBOT_LISTENER_API_VERSION = 3

    def __init__ ( self ):
        self.ROBOT_LIBRARY_LISTENER = self

    
    def continue_on_failure( func ):
        @wraps( func )
        def wrapper ( *args ):
            return BuiltIn().run_keyword_and_continue_on_failure( func.__name__, *args[1:]) # exclude self from args
        return wrapper

    @continue_on_failure
    def compareStuff (self, expected, current ):
        logger.info("In compareStuff")
        if expected == current:
            logger.info("This worked!!")
            return True
        raise AssertionError("This didn't work!")

And robot code, …/test.robot:
***Settings ***

Library ${CURDIR}/…/lib/test.py

*** Test Cases ***
Test: Run Keyword and Continue on Failure

compareStuff  1  1

compareStuff  1  2

compareStuff  3  2

The idea is that compareStuff() will be called and the wrapper will simply execute it as if it was called with ‘Run Keyword and Continue on Failure.’ I get a ‘Maximum limit of started keywords exceeded.’ error instead, it is very similar to the recurrsive calling issue as seen here: Maximum limit of started keywords exceeded. · Issue #2307 · robotframework/robotframework · GitHub
I was trying to use a class-based method for decorating but saw a pointer in the docs when using custom decorators to use functools.wraps functionality instead.

I am new to using custom decorators in this way, is this the wrong approach or could someone point me in the right direction to avoid the recursive nature of what I am seeing?

1 Like