Optional keyword argument

Hello all,

I would like to know whether RF syntax allows an optional keyword argument, with a default value.

Something like (pseudo):

Schedule a meeting ${time}
    IF ${time} == "default"
         ${current time} == date.get_current_time()
         Schedule a meeting at ${current time}
    ELSE
         Schedule a meeting at ${time}

So it would can be called either:
Schedule a meeting
or
Schedule a meeting at 15.2.2025 14:00

The default value can be either a predefined string, None or anything, that can be used for comparison.
I know I could for example use string “now” for scheduling at current time. But if possible would like to avoid it.

Thank you very much and best regards!
A

Possible with with embedded argument like in your example but docs says about embedded arguments:

Embedded arguments do not support default values or variable number of arguments like normal arguments do.

So, your case with default value would look like this:

Schedule a meeting 
    [Arguments]   ${time}=default
    IF ${time} == "default"
         ${current time} == date.get_current_time()
         Schedule a meeting at ${current time}
    ELSE
         Schedule a meeting at ${time}

These are documented @ Robot Framework User Guide

Thank you for your response sir.
I have tried with [Agruments] as well.

For the keyword to work, the argument needs to be passed with four spaces between the argument and rest of the keyword, like this:

Schedule a meeting at 15.2.2025 14:00
Is it possible to make it work without requirement for four spaces? Like this:
Schedule a meeting at 15.2.2025 14:00

Thank you!

Thats embedded argument and embedded argument does not have ability to set a default value - as stated in the docs.

Actually it is possible to have default values with embedded arguments, but it is a trick, not very clean.

it is possible to have default values with embedded arguments

Well, that’s more like a by-product of how the parser works and could go away as that’s not officially documented “feature” :slight_smile: I’d also make a guess that robotidy or robocop would complain about that.

1 Like

Here is my experiment. In practice you have two similar keywords.

*** Settings ***
Documentation     So it would can be called either:
...               Schedule a meeting
...               or
...               Schedule a meeting at 15.2.2025 14:00

*** Variables ***
${time}           ${EMPTY}

*** Keywords ***
Schedule a meeting${_time}
    [Setup]    _parse_data    ${_time}
    IF    "${time}" == "default"
        ${current time}=    Evaluate    f"{datetime.datetime.now()}"    datetime
        Schedule a meeting at ${current time}
    ELSE
        Schedule a meeting at ${time}
    END

_parse_data
    [Arguments]    ${_time}=${EMPTY}
    IF    ${_time.startswith('.')}
        Set Suite Variable    \${time}    default
    ELSE
        Set Suite Variable    \${time}    ${time.strip().replace('at ', '')}
    END

Schedule a meeting at ${time}
    Log    ${\n}Your meeting will happen at ${time}.    console=True

*** Test Cases ***
Call without arguments
    Schedule a meeting.

Call with arguments
    Schedule a meeting at 15.2.2025 14:00

1 Like

How about just having 2 keywords?

  1. Schedule a meeting
    and then
  1. Schedule a meeting at ${time}

Schedule a meeting can be a simple 1 line keyword that just calls Schedule a meeting at ${time} with the current time.

Dave.

1 Like

As others have pointed out, embedded arguments cannot have default values, but it is possible to construct a keyword that matches both Schedule a meeting and Schedule a meeting at 15.2.2025 14:00. In the former case the variable matching the time will contain an empty string, and you can replace it separately with the default value. The example below demonstrates this. It’s similar to earlier examples, but it has a separate variable matching at (including surrounding spaces) so that there’s no need to strip that away later.

*** Test Cases ***
Example
    Schedule a meeting
    Schedule a meeting at 15.2.2025 14:00

*** Keywords ***
Schedule a meeting${at:( at )?}${time}
    IF    not $time    VAR    ${time}    now
    Log to console    \n>${time}<

Although the above works, I believe we can make it better in the future. The most annoying part is the need to have the separate variable matching at. It makes it possible to define part of the keyword as a regular expression (that’s the :( at )? part) which is convenient, but it would be better if regexps could be used directly without a variable. Due to backwards compatibility reasons we cannot make the keyword name a regular expression by default, and due to the added complexity I’m not sure would it be a good idea in general. We could, however, support special markers like /<regexp>/ to indicate that we are using a regexp:

*** Keywords ***
/Schedule a meeting( at )?${time}/
    IF    not $time    VAR    ${time}    now
    Log to console    \n>${time}<

The other problem is the need to separately specify the default value. To avoid that, we needed to add support for default values with embedded arguments. Using the =<default> syntax like with “normal” arguments ought to work fine and be consistent, and I guess the semantics could be that the default value is used if the argument would otherwise get an empty string as its value. This enhancement combined with the earlier enhancement would allow us to write:

*** Keywords ***
/Schedule a meeting( at )?${time=now}/
    Log to console    \n>${time}<

The former enhancement to allow the whole keyword name to be a regexp has been discussed few times earlier, but I don’t think there’s an issue about that yet and there also hasn’t been agreement about the syntax. If you think this would be a nice addition, please submit an issue so we can continue discussing about the syntax alternatives there. If we decided to go with the /<regex>/ syntax, implementation shouldn’t be overly complicated, but there are some backwards compatibility concerns that need to be taken into account.

I don’t remember there being discussions about default values with embedded arguments earlier, but I consider that a convenient enhancement. If you agree, please submit an issue about it as well! There shouldn’t be need to discuss about the syntax and implementation ought to be easy as well, but also this enhancement has some backwards compatibility concerns to be taken into account.

3 Likes

And now since embedded arguments keywords can also use the [Arguments] setting, it could be possible to use:

*** Keywords ***
Schedule a meeting${at:( at )?}${time}
    [Arguments]    ${time}='now'
   (...)
2 Likes

Thank you all for your kind responses and apologies for the delayed response.

@HelioGuilherme66
Thank you for trying out the suggestion with arguments. I can see that it works as desired. I would however consider the additional complexity that comes with it.

@damies13
Your suggestion with using 2 keywords looks good, thank you. Having the option to add “now” (as an embedded argument) would make it more explicit. Though I could get by without it as well.

@pekkaklarck
Thank you for your input and suggestions on possible future enhancements. Frankly, I am not too familiar with Robot Framework yet, let alone follow the work being done on Github. Therefore I believe someone else would be a better fit for submitting and following the discussion. If so desired, I can give it a try as well.

Again, thank you everyone for your time and suggestions!

2 Likes