Something you may have misunderstanding in robotframework
- 1. Keyword
Run Keyword and Ignore Error
does not ignore all errors - 2. Keyword
Wait Until Keyword Succeeds
will fail before timeout - 3. RobotFramework will continue do the execution even if some keywords fail in teardown
- 4.
Stop Gracefully
injybot
will not stop immediately
There are many RobotFramework users, with huge amount of libraries, keywords, resources and test suites. But I guess there should be something you misunderstand of this framework. I listed some of them here, and if you have others, that should be very helpful if you post them in the comment.
1. Keyword Run Keyword and Ignore Error
does not ignore all errors
Sometimes we need to ignore the keyword execution error, such as an extra IP configuration. In most scenario, we will use BuiltIn keyword run keyword and ignore error
. But does it ignore all errors?
The answer is No. Below is the source code of this keyword.
try:
return 'PASS', self.run_keyword(name, *args)
except ExecutionFailed as err:
if err.dont_continue:
raise
return 'FAIL', unicode(err)
We can see, when err.dont_continue
is True
, this keyword will fail. And let’s see the code of ExecutionFailed
.
def dont_continue(self):
return self.timeout or self.syntax or self.exit
When timeout
or syntax
or exit
, it will return True
.
OK, until now, we know there are three scenarios run keyword and ignore error
will fail: Timeout, Syntax Error, Fatal Exception.
2. Keyword Wait Until Keyword Succeeds
will fail before timeout
Similar as run keyword and ignore error
, wait until keyword succeeds
is not always reliable. Sometimes it will fail before timeout reached.
Below is the while loop of this keyword.
while True:
try:
return self.run_keyword(name, *args)
except ExecutionFailed as err:
if err.dont_continue:
raise
count -= 1
if time.time() > maxtime > 0 or count == 0:
raise AssertionError("Keyword '%s' failed after retrying "
"%s. The last error was: %s"
% (name, message, err))
self._sleep_in_parts(retry_interval)
It raise in err.dont_continue
too. Same as the previous one.
3. RobotFramework will continue do the execution even if some keywords fail in teardown
RobotFramework does not fail the keyword immediately after running it. Actually, it catch the exception, and do different actions on different scenarios.
Let’s see the code.
# robot.running.keywordrunner.KeywordRunner
def run_keywords(self, keywords):
errors = []
for kw in keywords:
try:
self.run_keyword(kw)
except ExecutionPassed as exception:
exception.set_earlier_failures(errors)
raise exception
except ExecutionFailed as exception:
errors.extend(exception.get_errors())
if not exception.can_continue(self._context.in_teardown,
self._templated,
self._context.dry_run):
break
if errors:
raise ExecutionFailures(errors)
Here we can see, when the exception.can_continue(self._context.in_teardown)
is True
, the execution will not be interruptted. And can_continue
is as below:
def can_continue(self, teardown=False, templated=False, dry_run=False):
if dry_run:
return True
if self.dont_continue and not (teardown and self.syntax):
return False
if teardown or templated:
return True
return self.continue_on_failure
So everything is clear, when the keyword is in the teardown, it will not fail immediately.
4. Stop Gracefully
in jybot
will not stop immediately
Stop Gracefully
is an amazing feature of RobotFramework
. But it does not stop current keyword immediately in jybot
, why?
Let’s see the code.
# robot.running.signalhandler._StopSignalMonitor
def __call__(self, signum, frame):
self._signal_count += 1
LOGGER.info('Received signal: %s.' % signum)
if self._signal_count > 1:
sys.__stderr__.write('Execution forcefully stopped.\n')
raise SystemExit()
sys.__stderr__.write('Second signal will force exit.\n')
if self._running_keyword and not sys.platform.startswith('java'):
self._stop_execution_gracefully()
Obviously, when the platform is java
, it will not stop.