Setting boolean variables from the command line

2,112 views
Skip to first unread message

Alex Payne

unread,
Jul 20, 2017, 4:48:41 PM7/20/17
to robotframework-users
Hi,

Every variable passed to robot from the command line using the -v argument is automatically taken as a unicode string in robot.
I want to be able to specify a boolean variable from the command line.
This way I can just check if something is true or false instead of doing string comparisons.

Is there a way to do this already built in that I'm just missing?

Thanks,

Alex

Hélio Guilherme

unread,
Jul 21, 2017, 8:52:07 AM7/21/17
to robotframework-users
I did try some experiments and was not possible to pass a real boolean value, because when evaluating it would fail with value error (it was expecting either True or False). The only way I know is to pass a string value and then evaluate as strings. See the test below:


*** Variables ***
$
{exlogic}        ${EMPTY}


*** Test Cases ***
Truthy
   
Run Keyword If    "${exlogic}" == "True"    MyKeyword    ${exlogic}
   
Run Keyword Unless    "${exlogic}" == "True"    MyKeyword    ${exlogic}


*** Keywords ***
MyKeyword
   
[Arguments]    ${var}
   
Run Keyword If    "${var}" == "True"    Log    This is "\${var}"==${var} when is True
   
Run Keyword Unless    "${var}" == "True"    Log    This is "\${var}"==${var} when is Not True

Vincent Chow

unread,
Jul 21, 2017, 9:11:12 AM7/21/17
to robotframework-users
I just encountered this the other day. Pass in 0 or 1 for the respective boolean values. You can test this out by using the Should be True keyword.

Alex Payne

unread,
Jul 21, 2017, 11:17:26 AM7/21/17
to robotframework-users
Thank you for the help.
The reason that I want to have the value of these robot variables be Python's True and False bool objects is because we are passing them to python script from robot, and we don't want to do string comparisons in the Python code.

I am considering making an issue and PR to have robot automatically convert the "True" and "False" strings to their respective Python bool objects like robot's ${True} and ${False} variables.

Tatu Aalto

unread,
Jul 22, 2017, 2:12:01 AM7/22/17
to alexp...@gmail.com, robotframework-users
Ugh

It is true one can not set Python True or False from command line. But because you are building a Python script, then you could look in here: https://github.com/robotframework/robotframework/blob/master/src/robot/utils/robottypes.py and more details in here: http://robotframework.org/robotframework/latest/libraries/BuiltIn.html, in Boolean arguments chapter.

-Tatu
Send from my mobile

--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsub...@googlegroups.com.
To post to this group, send email to robotframework-users@googlegroups.com.
Visit this group at https://groups.google.com/group/robotframework-users.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Vincent Chow

unread,
Jul 25, 2017, 4:01:11 PM7/25/17
to robotframework-users
Have you tried what I suggested? Using 0 or 1?

Alex Payne

unread,
Jul 27, 2017, 10:22:21 AM7/27/17
to robotframework-users
Setting a variable to 0 or 1 from the command line still sets the variable to the unicode string "0" or "1" under the hood so we would still need to do some pre-processing or conversions.

Another reason I want to use the True of False boolean type objects is to keep things pythonic.

Bryan Oakley

unread,
Jul 27, 2017, 10:38:35 AM7/27/17
to robotframework-users
There is simply nothing you can do about this. bash (or whatever shell you're using) knows nothing about python datatypes, and robot has no support for defining the type of data passed in via a command line argument. 

If you have a keyword that requires a non-string argument, I recommend that your keywords do an explicit conversion:

    def my_keyword_with_typed_arguments(a_boolean, an_int):
        a_boolean = bool(a_boolean)
        an_int = int(an_int)
        ...

This is a simple solution, and lets you move on to more interesting problems. 

--

Kevin O.

unread,
Jul 27, 2017, 11:47:28 AM7/27/17
to robotframework-users
I agree with Bryan.
But I prefer the slightly more flexible is_truthy for type coercion to bool. It is a little more flexible than bool()

from robot.utils import is_truthy

def my_keyword(blah):
    blah = is_truthy(blah)


To post to this group, send email to robotframe...@googlegroups.com.

Alex Payne

unread,
Jul 27, 2017, 1:45:37 PM7/27/17
to robotframework-users
I understand there is no support for setting boolean values from the CLI with robot.  Unfortunately this is a hard requirement and I need to have the booleans.  So I am going to add this support.

Kevin O.

unread,
Jul 27, 2017, 4:53:08 PM7/27/17
to robotframework-users
FYI you can create variables of whatever type you like in variables files and reference the variables file on the command line.
In that way, setting boolean variables on the CLI is supported.

Tatu Aalto

unread,
Jul 28, 2017, 3:23:11 AM7/28/17
to alexp...@gmail.com, robotframework-users
Ugh

Are you sure that you want to go in that direction? Are you sure that you want your code to work differently if user defines string or Python True? Or if user defines string or Python None? If you are sure about this, could you describe a scenario where this could be useful, because I can not think a such scenario and would really love to hear such scenario.

I understand that you have a requirement that says that boolean values must be supported from command line. But it might be useful to understand where that requirement comes from and why they are wanting that feature. There might be better ways to implement that requirement but it's hard to give good advice, because we don't understand your requirements. 

I also have a need, sometimes, need to define booleans from command line and I define them as strings. But I have build my libraries in such way that they use robot.utils.is_truthy internally. Example:
if is_truthy(bool_arg):
    do_something(bool_arg)
else:
    ...

Also it might be worth while reading, how Python truth testing works [1].


-Tatu
Send from my mobile
I agree with Bryan.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsubscrib...@googlegroups.com.

To post to this group, send email to robotframe...@googlegroups.com.
Visit this group at https://groups.google.com/group/robotframework-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsubscrib...@googlegroups.com.
To post to this group, send email to robotframework-users@googlegroups.com.

Alex Payne

unread,
Jul 28, 2017, 7:20:12 AM7/28/17
to robotframework-users
External Python libraries are extracting the variables from robot to use as toggles. There are Python comparisons using `if myvar is True:`
We are also using boolean comparisons in robot using these variables. We need to avoid using string comparisons or conversions where we really expect to have Boolean values. It is important for me to have uniformity in this case and using all string values instead is not acceptable to the org. There are others consuming this code and I want to simplify it as much as possible so there are minimal nuances.

We don't want to use Python variable files because it becomes more complicated to override a robot variable from the command line.

Bryan Oakley

unread,
Jul 28, 2017, 7:55:36 AM7/28/17
to alexp...@gmail.com, robotframework-users
Have you considered creating a keyword that runs in suite setup that iterates over all of the variables, converting the ones that have the string values "True", "False", or "None" to the actual values? That should be pretty easy to write.

--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsub...@googlegroups.com.

Alex Payne

unread,
Jul 28, 2017, 10:28:27 AM7/28/17
to robotframework-users, alexp...@gmail.com
I have considered that, and that is probably what we will end up doing.
I was going to use a pre-run modifier, but the variables passed as command line arguments are not accessible at that point.


On Friday, July 28, 2017 at 7:55:36 AM UTC-4, Bryan Oakley wrote:
Have you considered creating a keyword that runs in suite setup that iterates over all of the variables, converting the ones that have the string values "True", "False", or "None" to the actual values? That should be pretty easy to write.
On Fri, Jul 28, 2017 at 6:20 AM, Alex Payne <alexp...@gmail.com> wrote:
External Python libraries are extracting the variables from robot to use as toggles. There are Python comparisons using `if myvar is True:`
We are also using boolean comparisons in robot using these variables. We need to avoid using string comparisons or conversions where we really expect to have Boolean values. It is important for me to have uniformity in this case and using all string values instead is not acceptable to the org. There are others consuming this code and I want to simplify it as much as possible so there are minimal nuances.

We don't want to use Python variable files because it becomes more complicated to override a robot variable from the command line.

--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsub...@googlegroups.com.
To post to this group, send email to robotframe...@googlegroups.com.

Kevin O.

unread,
Jul 28, 2017, 10:32:29 AM7/28/17
to robotframework-users, alexp...@gmail.com
I would consider Bryan's approach of getting in the middle and coercing things to bool so the libraries never see a string.
Also you could write wrappers for said libraries. This is a common practice due to the mismatch between RF using mostly strings for everything and libraries expecting int, bool, etc.
If these libraries were designed for RF, than they should be designed to accept strings, as is the norm in RF world. But it sounds like they were not designed for RF, in which case a wrapper would make sense to make the Python world interact better with RF code. This is  partially why we have things like Selenium2Library, SSHLibrary, SudsLibrary, etc.

On Friday, July 28, 2017 at 6:55:36 AM UTC-5, Bryan Oakley wrote:
Have you considered creating a keyword that runs in suite setup that iterates over all of the variables, converting the ones that have the string values "True", "False", or "None" to the actual values? That should be pretty easy to write.
On Fri, Jul 28, 2017 at 6:20 AM, Alex Payne <alexp...@gmail.com> wrote:
External Python libraries are extracting the variables from robot to use as toggles. There are Python comparisons using `if myvar is True:`
We are also using boolean comparisons in robot using these variables. We need to avoid using string comparisons or conversions where we really expect to have Boolean values. It is important for me to have uniformity in this case and using all string values instead is not acceptable to the org. There are others consuming this code and I want to simplify it as much as possible so there are minimal nuances.

We don't want to use Python variable files because it becomes more complicated to override a robot variable from the command line.

--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsub...@googlegroups.com.
To post to this group, send email to robotframe...@googlegroups.com.

Alex Payne

unread,
Jul 28, 2017, 11:30:48 AM7/28/17
to robotframework-users, alexp...@gmail.com
That sounds good but the only thing is that robot does still make use of the boolean values via ${True} and ${False}.
So if we plan on using the CLI to override variables, then we will need to choose between mixing string "True" and boolean ${True} in the test suites or converting them on the fly.  Either one I feel is not an idea design choice.

Chris Newman

unread,
Jul 28, 2017, 11:32:42 AM7/28/17
to Alex Payne, robotframework-users
On 28 Jul 2017, at 4:20, Alex Payne wrote:
> External Python libraries are extracting the variables from robot to
> use as toggles. There are Python comparisons using `if myvar is True:`
> We are also using boolean comparisons in robot using these variables.
> We need to avoid using string comparisons or conversions where we
> really expect to have Boolean values. It is important for me to have
> uniformity in this case and using all string values instead is not
> acceptable to the org.

Robot Framework and Python are two separate programming languages with
different best practices. The best practice for Robot Framework is to
use string variables for most tasks. When interfacing these two
languages, the best practice is to use is_truthy() as the boolean
translation interface. In your attempt to hide Robot Framework semantics
from your Python code, you're going outside the best practices. This
will be more work and will result in code that is harder to maintain for
someone familiar with Robot Framework (even if the Python code is easier
to maintain for someone ignorant of Robot Framework). Are you sure you
want to prioritize Python type purity over best practice use of Robot
Framework? That choice will have consequences.

> There are others consuming this code and I want to simplify it as much
> as possible so there are minimal nuances.

Both Python and Robot Framework have nuances. In my experience it's
simpler to accept and document the presence of nuances rather than
trying to hide them. Attempts to hide nuances tend to fail at unexpected
times.

> We don't want to use Python variable files because it becomes more
> complicated to override a robot variable from the command line.

- Chris

Pekka Klärck

unread,
Jul 29, 2017, 5:32:30 AM7/29/17
to alexp...@gmail.com, robotframework-users
Hello,

and thanks for a great question that has spurred an interesting
discussion. I've been on holiday mode without access to a laptop and
thus haven't had a real change to participate earlier.

As others have pointed out, when you pass values like `whetever` or
`True` or `42` from Robot Framework data or from the command line,
Robot is going to get that in as a string. In the early days we could
have considered automatically converting values that look like
numbers, booleans, dates, etc. to respective Python data types, but
that would have created problems if you actually want to pass those
values as strings. Languages like YAML solve this by requiring quoting
strings in these cases, but in my opinion that's confusing and creates
another problem with handling quotes. We could argue about this, but
in reality the ship has sailed and we simply cannot change the
semantics without causing huge backwards compatibility problems.

A general good practice with Robot is to implement libraries so that
they know about the feature/limitation that values in general come in
as strings. This is typically easy when you create library to be used
with Robot. Numbers you can handle simply with `int` or `float`, and
booleans are best handled with the already mentioned
`robot.utils.is_truthy` function that also considers string `False`
(case-insensitively) to be false. We should actually add a similar
`is_noney` function to handle string `None` that libraries could use.
If you implement Python module to be used both as a Robot library and
as a normal Python module, handling string values like this may be a
bit strange, but I don't think it typically really matters a lot. If
that's unacceptable, or if you are planning to use an existing Python
module as a Robot library, a good and already proposed solution is
creating a thin wrapper library that handles argument conversion and
possibly other tasks like logging, and keep the reusable Python code
in an external module. If argument conversion is not done, in the test
data it's always possible to use variables to pass actual booleans,
numbers, or `None` like `${True}`, `${42}` and `${None}`. This makes
the data somewhat ugly and I always recommend doing the conversion on
the library side.

Although explicitly converting arguments into desired types isn't that
big a task, it's still bit annoying and repetitive and adds some extra
code. What we could consider doing is adding a possibility for the
libraries to specify argument types and then do conversion on Robot
side automatically. This is actually already done with Java based
libraries (a feature requested by Craig Larman years ago) based on the
explicit types you must use with Java code anyway. Utilizing the same
code with Python libraries shouldn't be too hard, but that obviously
requires having type information available. If Python 3 support would
be enough, we could simply use type annotations it provides, but being
able to specify argument types using the `@keyword` decorator
shouldn't be too complicated to support either.

The actual question was about handling `True` given from the command
line, and I noticed you had submitted an issue about it too. As you
probably can guess based on the explanation above, I'm not too fond of
the idea. It would be inconsistent compared to handling `True` on the
test data and, more importantly, inconsistent with handling numbers on
the command line. The change would also be backwards incompatible, and
more so if we'd also handle numbers in addition to booleans.

What we could consider instead is adding support for using variables
in variable values passed from the command line. This would allow
using the aforementioned special variables like `--variable xxx:${42}`
and being able to refer other variables might be sometimes handy too.
On unixy machines you needed to single quote values containing
variables to prevent the shell from resolving them, but that shouldn't
be too big a problem. As others already mentioned, you can also use
variable files (both Python and YAML) to provide non-string values
from the command line pretty easily.

Cheers,
.peke
--
Agile Tester/Developer/Consultant :: http://eliga.fi
Lead Developer of Robot Framework :: http://robotframework.org

Alex Payne

unread,
Aug 1, 2017, 10:05:48 AM8/1/17
to robotframework-users, alexp...@gmail.com
Hi,

Thank you for the response. We aren't using Python3 yet but adding support for passing in variables like --variable xxx:${True} might work.
I'm going to try making the conversion in a global suite setup first.
I appreciate everyone's response and input on this topic.  It has been very helpful.

Thanks,

Alex

Bryan Oakley

unread,
Aug 1, 2017, 10:43:36 AM8/1/17
to robotframework-users
perhaps a more general solution would be to embed type information in the command line argument so it works for more than booleans and special variables. For example:

robot --variable foo:int:42 --variable bar:bool:true --variable baz:float:3.1415

or with a prefix:

robot --variable (int)foo:42  --variable (bool)bar:true  --variable (float)baz:3.1415


Then, the code that processes the command line arguments could pull out the type information and do the transformation automatically. If there are concerns about backward compatibility, you could introduce a new argument like --typedvariable foo:int:42.



--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsub...@googlegroups.com.
To post to this group, send email to robotframework-users@googlegroups.com.

Pekka Klärck

unread,
Aug 1, 2017, 5:06:14 PM8/1/17
to Oakley, Bryan, robotframework-users
2017-08-01 17:43 GMT+03:00 Bryan Oakley <bryan....@gmail.com>:
> perhaps a more general solution would be to embed type information in the
> command line argument so it works for more than booleans and special
> variables. For example:
>
> robot --variable foo:int:42 --variable bar:bool:true --variable
> baz:float:3.1415

I was thinking about this exact solution too. It would make it
possible to support booleans, numbers and None. An alternative would
be allowing something like `--variable foo:True:eval` that would tell
Robot to evaluate the value in Python. Although these would solve the
underlying issue, they wouldn't be too much better than just using
variable files.

My next though was supporting variables in variable values like
`--variable foo:${True}`. Somehow I feel this easier to understand
than the above alternatives, and being able to refer to other global
variables (including built-in variables) would sometimes be handy too.
From backwards compatibility point of view both `foo:True:bool` and
`foo:${True}` are equivalent.

Pekka Klärck

unread,
Aug 1, 2017, 5:15:31 PM8/1/17
to Alex Payne, robotframework-users
2017-08-01 17:05 GMT+03:00 Alex Payne <alexp...@gmail.com>:
>
> Thank you for the response. We aren't using Python3 yet but adding support
> for passing in variables like --variable xxx:${True} might work.


I assume that with Python 3 reference you mean my idea to support
automatic argument conversion if a Python keyword has type annotation.
That would be a really nice feature, but it would be too much more
work to support also argument types when using the @keyword decorator:

from robot.api.deco import keyword

@keyword(argtypes=[int, bool])
def example(count, log=True):
# ...

If an argument has a default value, like the example above has, we
could automatically inspect the argument type too.

Even if automatic argument type conversion would be implemented, being
able to pass non-string argument values from the command line would
still be sometimes useful. For that purpose my current favorite is
using `--variable xx:${True}`. That ought to be very easy to implement
and, assuming we are OK with the small backwards incompatibility,
could be done already in RF 3.0.3. Automatic argument type conversion
requires bigger changes and is possible only in a major version.

Bryan Oakley

unread,
Aug 1, 2017, 6:21:59 PM8/1/17
to Pekka Klärck, Alex Payne, robotframework-users
The disadvantage to --variable xx:${True} is that it's limited to robot's own parsing of the value, which is fairly limited. If the type information were embedded in the argument then a lot more formats could be supported. For example:  --variable xx:list:1,2,3 to specify a list of values, or even --variable xx:json:{'name': 'Foo', 'age': 42} to pass in some rich data. 

All of that being said, I can probably think of a dozen other things I'd rather see fixed or added to the core before this feature. 

Alex Payne

unread,
Aug 2, 2017, 12:15:20 PM8/2/17
to robotframework-users, pe...@iki.fi, alexp...@gmail.com
I'm going to generate a python dictionary using the get_variables() method and robot's variablefile argument.
Many of the ideas put forth would work but we aren't ready to modify the core.

To post to this group, send email to robotframe...@googlegroups.com.

Alex Payne

unread,
Aug 3, 2017, 10:16:10 AM8/3/17
to robotframework-users, pe...@iki.fi, alexp...@gmail.com
That solution ultimately worked.  I have a wrapper around the robot cli.  I am generating a list of argument to pass to a variable file, and from there I'm converting them from sting to boolean.
Reply all
Reply to author
Forward
0 new messages