Skip to content

Commit 30d87e4

Browse files
committed
Enhance variable type conversion documentation
Fixes #3278.
1 parent e9fb143 commit 30d87e4

File tree

4 files changed

+311
-245
lines changed

4 files changed

+311
-245
lines changed

doc/userguide/src/CreatingTestData/ControlStructures.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,28 @@ requires using dictionaries as `list variables`_:
534534
Robot Framework 3.2. With earlier version it is possible to iterate
535535
over dictionary keys like the last example above demonstrates.
536536

537+
Loop variable conversion
538+
~~~~~~~~~~~~~~~~~~~~~~~~
539+
540+
`Variable type conversion`_ works also with FOR loop variables. The desired type
541+
can be added to any loop variable by using the familiar `${name: type}` syntax.
542+
543+
.. sourcecode:: robotframework
544+
545+
*** Test Cases ***
546+
Variable conversion
547+
FOR ${value: bytes} IN Hello! Hyvä! \x00\x00\x07
548+
Log ${value} formatter=repr
549+
END
550+
FOR ${index} ${date: date} IN ENUMERATE 2023-06-15 2025-05-30 today
551+
Log ${date} formatter=repr
552+
END
553+
FOR ${item: tuple[str, date]} IN ENUMERATE 2023-06-15 2025-05-30 today
554+
Log ${item} formatter=repr
555+
END
556+
557+
.. note:: Variable type conversion is new in Robot Framework 7.3.
558+
537559
Removing unnecessary keywords from outputs
538560
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
539561

doc/userguide/src/CreatingTestData/CreatingUserKeywords.rst

Lines changed: 111 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -480,47 +480,87 @@ with and without default values is not important.
480480
[Arguments] @{} ${optional}=default ${mandatory} ${mandatory 2} ${optional 2}=default 2 ${mandatory 3}
481481
Log Many ${optional} ${mandatory} ${mandatory 2} ${optional 2} ${mandatory 3}
482482

483-
Variable type in user keywords
484-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
485-
486-
Arguments in user keywords support optional type definition syntax, as it
487-
is explained in `Variable type conversion`_ section. The type definition
488-
syntax starts with a colon, contains a space and is followed by the type
489-
name, then variable must be closed with closing curly brace. The type
490-
definition is stripped from the variable name and variable must be used
491-
without it in the keyword body. In the example below, the `${arg: int}`,
492-
contains type int, the type definition `: int` is stripped from the
493-
variable name and the variable is used as `${arg}` in the keyword body.
483+
__ https://www.python.org/dev/peps/pep-3102
484+
__ `Variable number of arguments with user keywords`_
485+
__ `Positional arguments with user keywords`_
486+
__ `Free named arguments with user keywords`_
487+
__ `Default values with user keywords`_
488+
489+
Argument conversion with user keywords
490+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
491+
492+
User keywords support automatic argument conversion based on explicitly specified
493+
types. The type syntax `${name: type}` is the same, and the supported conversions
494+
are the same, as when `creating variables`__.
495+
496+
The basic usage with normal arguments is very simple. You only need to specify
497+
the type like `${count: int}` and the used value is converted automatically.
498+
If an argument has a default value like `${count: int}=1`, also the default
499+
value will be converted. If conversion fails, calling the keyword fails with
500+
an informative error message.
494501

495502
.. sourcecode:: robotframework
496503

504+
*** Test Cases ***
505+
Move around
506+
Move 3
507+
Turn LEFT
508+
Move 2.3 log=True
509+
Turn right
510+
511+
Failing move
512+
Move bad
513+
514+
Failing turn
515+
Turn oops
516+
497517
*** Keywords ***
498-
Default
499-
[Arguments] ${arg: int}=1
500-
Should be equal ${arg} 1 type=int
518+
Move
519+
[Arguments] ${distance: float} ${log: bool}=False
520+
IF ${log}
521+
Log Moving ${distance} meters.
522+
END
523+
524+
Turn
525+
[Arguments] ${direction: Literal["LEFT", "RIGHT"]}
526+
Log Turning ${direction}.
527+
528+
.. tip:: Using `Literal`, like in the above example, is a convenient way to
529+
limit what values are accepted.
501530

502-
Free named arguments can also have type definitions, but the argument
503-
does not support type definition for keys. Only type for value(s) can be
504-
defined. In Python the key is always string. In the example below, the
505-
`${named: `int|float`}` contains type `int|float`. All the keys are
506-
strings and values are converted either to int or float.
531+
When using `variable number of arguments`__, the type is specified like
532+
`@{numbers: int}` and is applied to all arguments. If arguments may have
533+
different types, it is possible to use an union like `@{numbers: float | int}`.
534+
With `free named arguments`__ the type is specified like `&{named: int}` and
535+
it is applied to all argument values. Converting argument names is not supported.
507536

508537
.. sourcecode:: robotframework
509538

510539
*** Test Cases ***
511-
Test
512-
Type With Free Names Only a=1 b=2.3
540+
Varargs
541+
Send bytes Hello! Hyvä! \x00\x00\x07
542+
543+
Free named
544+
Log releases rc 1=2025-05-08 rc 2=2025-05-19 rc 3=2025-05-21 final=2025-05-30
513545

514546
*** Keywords ***
515-
Type With Free Names Only
516-
[Arguments] ${named: `int|float`}
517-
Should be equal ${named} {"a":1, "b":2.3} type=dict
547+
Send bytes
548+
[Arguments] @{data: bytes}
549+
FOR ${value} IN @{data}
550+
Log ${value} formatter=repr
551+
END
518552

519-
__ https://www.python.org/dev/peps/pep-3102
553+
Log releases
554+
[Arguments] &{releases: date}
555+
FOR ${version} ${date} IN &{releases}
556+
Log RF 7.3 ${version} was released on ${date.day}.${date.month}.${date.year}.
557+
END
558+
559+
.. note:: Argument conversion with user keywords is new in Robot Framework 7.3.
560+
561+
__ `Variable type syntax`_
520562
__ `Variable number of arguments with user keywords`_
521-
__ `Positional arguments with user keywords`_
522563
__ `Free named arguments with user keywords`_
523-
__ `Default values with user keywords`_
524564

525565
.. _Embedded argument syntax:
526566

@@ -772,16 +812,13 @@ If needed, custom patterns can be prefixed with `inline flags`__ such as
772812
`(?i)` for case-insensitivity.
773813

774814
Using custom regular expressions is illustrated by the following examples.
775-
Notice that the first one shows how the earlier problem with
776-
:name:`Select ${city} ${team}` not matching :name:`Select Los Angeles Lakers`
777-
properly can be resolved without quoting. That is achieved by implementing
778-
the keyword so that `${team}` can only contain non-whitespace characters.
815+
The first one shows how the earlier problem with :name:`Select ${city} ${team}`
816+
not matching :name:`Select Los Angeles Lakers` properly can be resolved without
817+
quoting by implementing the keyword so that `${team}` can only contain non-whitespace
818+
characters.
779819

780820
.. sourcecode:: robotframework
781821

782-
*** Settings ***
783-
Library DateTime
784-
785822
*** Test Cases ***
786823
Do not match whitespace characters
787824
Select Chicago Bulls
@@ -807,13 +844,10 @@ the keyword so that `${team}` can only contain non-whitespace characters.
807844
${result} = Evaluate ${number1} ${operator} ${number2}
808845
Should Be Equal As Integers ${result} ${expected}
809846

810-
Deadline is ${date:(\d{4}-\d{2}-\d{2}|today)}
811-
IF '${date}' == 'today'
812-
${date} = Get Current Date
813-
ELSE
814-
${date} = Convert Date ${date}
815-
END
816-
Log Deadline is on ${date}.
847+
Deadline is ${deadline: date:\d{4}-\d{2}-\d{2}|today}
848+
# The ': date' part of the above argument specifies the argument type.
849+
# See the separate section about argument conversion for more information.
850+
Log Deadline is ${deadline.day}.${deadline.month}.${deadline.year}.
817851

818852
Select ${animal:(?i)cat|dog}
819853
[Documentation] Inline flag `(?i)` makes the pattern case-insensitive.
@@ -895,8 +929,8 @@ is not a single variable.
895929
Deadline is ${YEAR}-${MONTH}-${DAY}
896930

897931
*** Keywords ***
898-
Deadline is ${date:\d{4}-\d{2}-\d{2}}
899-
Log Deadline is ${date}
932+
Deadline is ${deadline:\d{4}-\d{2}-\d{2}}
933+
Should Be Equal ${deadline} 2011-06-27
900934

901935
Another limitation of using variables is that their actual values are not matched
902936
against custom regular expressions. As the result keywords may be called with
@@ -906,6 +940,40 @@ For more information see issue `#4462`__.
906940

907941
__ https://github.com/robotframework/robotframework/issues/4462
908942

943+
Argument conversion with embedded arguments
944+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
945+
946+
User keywords accepting embedded arguments support argument conversion with type
947+
syntax `${name: type}` similarly as `normal user keywords`__. If a `custom pattern`__
948+
is needed, it can be separated with an additional colon like `${name: type:pattern}`.
949+
950+
.. sourcecode:: robotframework
951+
952+
*** Test Cases ***
953+
Example
954+
Buy 3 books
955+
Deadline is 2025-05-30
956+
957+
*** Keywords ***
958+
Buy ${quantity: int} books
959+
Should Be Equal ${quantity} ${3}
960+
961+
Deadline is ${deadline: date:\d{4}-\d{2}-\d{2}}
962+
Should Be Equal ${deadline.year} ${2025}
963+
Should Be Equal ${deadline.month} ${5}
964+
Should Be Equal ${deadline.day} ${30}
965+
966+
Because the type separator is a colon followed by a space (e.g. `${arg: int}`)
967+
and the pattern separator is just a colon (e.g. `${arg:\d+}`), there typically
968+
are no conflicts when using only a type or only a pattern. The only exception
969+
is using a pattern starting with a space, but in that case the space can be
970+
escaped like `${arg:\ abc}` or a type added like `${arg: str: abc}`.
971+
972+
.. note:: Argument conversion with user keywords is new in Robot Framework 7.3.
973+
974+
__ `Argument conversion with user keywords`_
975+
__ `Using custom regular expressions`_
976+
909977
Behavior-driven development example
910978
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
911979

0 commit comments

Comments
 (0)