2014-12-04 14:12 GMT+01:00 Michael Walle <
mic...@walle.cc>:
>
> Is there a way to compare a value with the actual value None?
>
> Consider the following statement:
>
> Run Keyword If '${value}' is not 'None' My Keyword
>
> Now if ${value} is None the keyword is not run, but in case ${value} is the
> string 'None' it is not executed either, which is wrong IMHO.
I agree this can feel weird, but the result is exactly as designed.
> I guess this isn't possible with the current syntax/keyword, because you
> always have to convert ${value} to a string (by putting it in quotes) and
> the you'll lost the information whether it was None or an actual string.
Yes, the expression you used above will be string `'None' is not
'None'` when passed to `Run Keyword If` regardless is ${value} "real"
`None` or string `'None'`. When this expression is evaluated in Python
you typically get False, but the result is actually ambiguous [1].
If the argument passed to `Run Keyword If` is not a string, it will
not be evaluated but rather its truth value is checked directly. I
first thought you could just pass ${value} alone to `Run Keyword If`,
but the I realized that when it contains a string, evaluation will
fail with SyntaxError (unless the string happens to contain a valid
Python expression, in which case the result depends on that
expression). There are, however, at least three somewhat ugly/hackish
ways to use to actually get what you wanted.
1) Check is the value string or None like Guy already proposed:
${is none} = Run Keyword And Return Status Should Be Equal
${value} ${None}
Run Keyword If ${is string} My Keyword
This is both quite ugly and long, but shouldn't be too hard to
understand and ought to work regardless what ${value} actually
contains.
2) Use extended variable syntax [2] to check the type so that the end
result of the variable is just True or False:
Run Keyword If ${value.__class__ is not type(None)} My Keyword
Compared to the above solution this is just one line, but the
expression is _really_ ugly. It's a shame that using a bit nicer
Run Keyword If ${value is None} My Keyword
doesn't work because it has no non-alphanumeric chars after the
variable base name and thus it doesn't match extended variable syntax.
I guess we could extend the extended variable syntax to support also
`is` (and perhaps also `in`) operator when finding variable base
names.
3) Use extended variable syntax to get repr() of the variable value.
With strings this repr has quotes so they can be evaluated fine:
Run Keyword If ${value.__repr__()} is None My Keyword
This solution has a downside that it fails with SyntaxError if the
object has a repr that cannot be evaluated. That shouldn't be a
problem with base types, but you can have issues with custom objects.
Also in this case there would be more Pythonic way to get the repr
which doesn't work due to extended variable syntax limitations:
Run Keyword If ${repr(value)} is None My Keyword
We could take a look supporting wrapping variables with function like
this, but I'm not sure how reliable it could be done and how readable
the syntax actually is.
Does anyone have any other ideas how to solve this problem? With more
complex checks it would probably be best just to move the logic to a
custom library, but this particular case is something I hope could be
done cleanly also on Robot data level. Should we consider extending
the extended variable syntax like discussed in 2) and 3) above?
Cheers,
.peke
[1] `is` operator in Python verifies object identity. When comparing
short strings the result typically is same as with `==` operator that
verifies equality, because Python keeps short strings in memory and
reuses them. This is an implementation detail and shouldn't be relied
on, though.
[2]
http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#extended-variable-syntax
--
Agile Tester/Developer/Consultant ::
http://eliga.fi
Lead Developer of Robot Framework ::
http://robotframework.org