在自动化测试种,重复执行相同的动作多次是一个相当常见的操作,robotframework 有自己的循环结构

basic loop syntax:

   FOR  item  IN sequence

     do something

  END

simple for loop

*** Test Cases ***
Example
FOR ${animal} IN cat dog
Log ${animal}
Log 2nd keyword
END
Log Outside loop

Second Example
FOR ${var} IN one two ${3} four ${five}
... kuusi 7 eight nine ${last}
Log ${var}
END
Three Example
FOR ${element} IN @{ELEMENTS}
Start Element ${element}
END

在第一个例子中,循环执行了两次,依次赋值为 cat, dog, 循环体内有有两个log 语句

在第二个例子中,sequence被分割成了两行,循环总共执行10次

在第三个例子中,sequence是个列表,依次操作列表中的元素

Old for loop syntax

*** Test Cases ***
Example
:FOR ${animal} IN cat dog
\ Log ${animal}
\ Log 2nd keyword
Log Outside loop

旧的语法在Robot Framework 3.2中已经弃用,而对它的支持在Robot Framework 4.0中被完全移除

Nested for loops(嵌套循环)

从Robot Framework 4.0开始,只需在循环中添加另一个循环,就可以使用嵌套的for循环

*** Keywords ***
Handle Table
[Arguments] @{table}
FOR ${row} IN @{table}
FOR ${cell} IN @{row}
Handle Cell ${cell}
END
END

对于表格的循环,一行一行的去查找数据

*** Test Cases ***
Example
FOR ${root} IN r1 r2
FOR ${child} IN c1 c2 c3
FOR ${grandchild} IN g1 g2
Log Many ${root} ${child} ${grandchild}
END
END
FOR ${sibling} IN s1 s2 s3
Log Many ${root} ${sibling}
END
END

在早期的Robot Framework版本中,不直接支持循环嵌套,但可以在循环中使用一个user关键字,然后在那里创建另一个循环

Using several loop variables

也可以使用多个循环变量。语法与普通for循环相同,但所有循环变量都列在for和in之间的单元格中。可以有任意数量的循环变量,但是值的数量必须能均匀地除以变量的数量。

如果有很多值需要迭代,将它们组织在循环变量下面通常是很方便的,就像下面例子的第一个循环:

*** Test Cases ***
Three loop variables
FOR ${index} ${english} ${finnish} IN
... 1 cat kissa
... 2 dog koira
... 3 horse hevonen
Add to dictionary ${english} ${finnish} ${index}
END
FOR ${name} ${id} IN @{EMPLOYERS}
Create ${name} ${id}
END

For-in-range loop

前面的for循环总是在一个序列上迭代,这也是最常见的用例。有时,使用for循环执行一定次数仍然很方便,而Robot Framework为此也有一个特殊的for  item  IN RANGE  limit 语法。此语法源自python range()函数。

与其他for循环类似,for-in-range循环以for开始,循环变量位于下一个单元格中。在这种格式中,只能有一个循环变量,它包含当前循环索引。下一个单元格必须包含IN RANGE(区分大小写)和随后的单元格循环限制。

在最简单的情况下,只指定循环的上限。在本例中,循环索引从0开始,增加1直到限制,但不包括限制。也可以给出开始和结束的限制。然后索引从起始限制开始,但增长与简单情况类似。最后,还可以指定步长值来指定要使用的增量。如果步长是负的,它被用作减量。

可以使用范围限制的简单算术,如加减。当使用变量指定限制时,这尤其有用。Start、end和step通常以整数形式给出,但也可以使用浮点值。

*** Test Cases ***
Only upper limit
[Documentation] Loops over values from 0 to 9
FOR ${index} IN RANGE 10
Log ${index}
END

Start and end
[Documentation] Loops over values from 1 to 10
FOR ${index} IN RANGE 1 11
Log ${index}
END

Also step given
[Documentation] Loops over values 5, 15, and 25
FOR ${index} IN RANGE 5 26 10
Log ${index}
END

Negative step
[Documentation] Loops over values 13, 3, and -7
FOR ${index} IN RANGE 13 -13 -10
Log ${index}
END

Arithmetic
[Documentation] Arithmetic with variable
FOR ${index} IN RANGE ${var} + 1
Log ${index}
END

Float parameters
[Documentation] Loops over values 3.14, 4.34, and 5.54
FOR ${index} IN RANGE 3.14 6.09 1.2
Log ${index}
END

For-in-enumerate loop

有时,循环遍历列表并跟踪您在列表中的位置是有用的。robot有一个特殊的 ​​FOR index ... IN ENUMERATE ...​​语法。此语法源自Python内置的enumerate()函数。

(1)FOR- IN - ENUMERATE循环的工作方式与常规的for循环一样,只是循环变量后面的单元格必须是IN ENUMERATE(区分大小写),并且它们必须在任何其他循环变量之前有一个额外的索引变量。索引变量第一次迭代的值是0,第二次是1,以此类推。

例如,下面两个测试用例做相同的事情:

*** Variables ***
@{LIST} a b c

*** Test Cases ***
Manage index manually
${index} = Set Variable -1
FOR ${item} IN @{LIST}
${index} = Evaluate ${index} + 1
My Keyword ${index} ${item}
END

For-in-enumerate
FOR ${index} ${item} IN ENUMERATE @{LIST}
My Keyword ${index} ${item}
END

(2)从robot 4.0开始,可以使用start=number, 来指定索引从哪个数字开始递增,跟序列中的实际位置没有关系,比如序列中有三个元素,start=0, 则索引依次显示为0,1,2; start=10, 索引依次显示为10,11,12

*** Variables ***
@{LIST} a b c
${START} 10

*** Test Cases ***
For-in-enumerate with start
FOR ${index} ${item} IN ENUMERATE @{LIST} start=0
My Keyword ${index} ${item}
END

Start as variable
FOR ${index} ${item} IN ENUMERATE @{LIST} start=${start}
My Keyword ${index} ${item}
END

ride 执行结果:

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.016_TC_For-in-enumerate with start
20210721 16:52:10.240 : INFO : 0
20210721 16:52:10.241 : INFO : a
20210721 16:52:10.243 : INFO : 1
20210721 16:52:10.244 : INFO : b
20210721 16:52:10.247 : INFO : 2
20210721 16:52:10.247 : INFO : c
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.016_TC_For-in-enumerate with start

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.017_TC_Start as variable
20210721 16:52:10.253 : INFO : 10
20210721 16:52:10.253 : INFO : a
20210721 16:52:10.256 : INFO : 11
20210721 16:52:10.257 : INFO : b
20210721 16:52:10.259 : INFO : 12
20210721 16:52:10.260 : INFO : c
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.017_TC_Start as variable

(3)就像常规的for循环一样,你可以在每次循环迭代中循环多个值,只要你的列表中的值的数量能被循环变量的数量整除(不包括第一个,index变量):

*** Test Case ***
For-in-enumerate with two values per iteration
FOR ${index} ${en} ${fi} IN ENUMERATE
... cat kissa
... dog koira
... horse hevonen
Log "${en}" in English is "${fi}" in Finnish (index: ${index})
END

ride执行结果

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.018_TC_For-in-enumerate with two values per iteration
20210721 17:02:23.987 : INFO : "cat" in English is "kissa" in Finnish (index: 0)
20210721 17:02:23.989 : INFO : "dog" in English is "koira" in Finnish (index: 1)
20210721 17:02:23.991 : INFO : "horse" in English is "hevonen" in Finnish (index: 2)
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.018_TC_For-in-enumerate with two values per iteration

(4)如果你只在for-in-enumerate循环中使用一个循环变量,该变量将成为包含索引和迭代值的Python元组:

*** Variables ***
@{LIST} a b c
*** Test Case ***
For-in-enumerate with one loop variable
FOR ${x} IN ENUMERATE @{LIST}
Length Should Be ${x} 2
Log Index is ${x}[0] and item is ${x}[1].
END

ride执行结果

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.019_TC_For-in-enumerate with one loop variable
20210721 17:05:50.303 : INFO : Length is 2
20210721 17:05:50.304 : INFO : Index is 0 and item is a.
20210721 17:05:50.307 : INFO : Length is 2
20210721 17:05:50.309 : INFO : Index is 1 and item is b.
20210721 17:05:50.313 : INFO : Length is 2
20210721 17:05:50.315 : INFO : Index is 2 and item is c.
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.019_TC_For-in-enumerate with one loop variable

For-in-zip loop

(1)有些测试建立几个相关的列表,然后将它们一起循环。机器人框架对于这种情况有一个快捷方式:for…in zip …,它源自Python内置的zip()函数。

*** Variables ***
@{NUMBERS} ${1} ${2} ${5}
@{NAMES} one two five

*** Test Cases ***
Iterate over two lists manually
${length}= Get Length ${NUMBERS}
FOR ${index} IN RANGE ${length}
Log Many ${NUMBERS}[${index}] ${NAMES}[${index}]
END

For-in-zip
FOR ${number} ${name} IN ZIP ${NUMBERS} ${NAMES}
Log Many ${number} ${name}
END

ride执行结果

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.020_TC_Iterate over two lists manually
20210721 17:10:54.356 : INFO : Length is 3
20210721 17:10:54.356 : INFO : ${length} = 3
20210721 17:10:54.358 : INFO : 1
20210721 17:10:54.359 : INFO : one
20210721 17:10:54.361 : INFO : 2
20210721 17:10:54.361 : INFO : two
20210721 17:10:54.364 : INFO : 5
20210721 17:10:54.364 : INFO : five
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.020_TC_Iterate over two lists manually

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.021_TC_For-in-zip
20210721 17:10:54.369 : INFO : 1
20210721 17:10:54.370 : INFO : one
20210721 17:10:54.372 : INFO : 2
20210721 17:10:54.372 : INFO : two
20210721 17:10:54.374 : INFO : 5
20210721 17:10:54.375 : INFO : five
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.021_TC_For-in-zip

(2)与for-in-range循环和for- IN -enumerate类似,for-in-zip循环要求循环变量后的单元格读取IN ZIP(区分大小写)。for-in-zip循环使用的值必须是列表或类似列表的对象。当最短列表耗尽时,循环将停止。

要迭代的列表必须总是以标量变量(如${items})的形式给出,或者以列表变量(如@{Lists})的形式给出,这些变量产生实际的迭代列表。前一种方法更常见,上面已经演示过了。后一种方法是这样的:

*** Variables ***
@{NUMBERS} ${1} ${2} ${5}
@{NAMES} one two five
@{LISTS} ${NUMBERS} ${NAMES}

*** Test Cases ***
For-in-zip
FOR ${number} ${name} IN ZIP @{LISTS}
Log Many ${number} ${name}
END

ride执行结果

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.022_TC_LISTS_For-in-zip
20210721 17:14:51.716 : INFO : 1
20210721 17:14:51.717 : INFO : one
20210721 17:14:51.719 : INFO : 2
20210721 17:14:51.719 : INFO : two
20210721 17:14:51.721 : INFO : 5
20210721 17:14:51.721 : INFO : five
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.022_TC_LISTS_For-in-zip

迭代列表的数量没有限制,但必须与循环变量的数量匹配。或者,也可以只有一个循环变量,然后它变成一个Python元组,从所有列表中获取项目。

*** Variables ***
@{ABC} a b c
@{XYZ} x y z
@{NUM} 1 2 3 4 5

*** Test Cases ***
For-in-zip with multiple lists
FOR ${a} ${x} ${n} IN ZIP ${ABC} ${XYZ} ${NUM}
Log Many ${a} ${x} ${n}
END

For-in-zip with one variable
FOR ${items} IN ZIP ${ABC} ${XYZ} ${NUM}
Length Should Be ${items} 3
Log Many ${items}[0] ${items}[1] ${items}[2]
END

ride执行结果:如果列表的项数不相等,那么最短列表定义有多少次迭代,而长列表末尾的值将被忽略。例如,上面的示例只循环三次,${NUM}列表中的值4和5将被忽略。

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.023_TC_For-in-zip with multiple lists
20210721 17:18:27.545 : INFO : a
20210721 17:18:27.546 : INFO : x
20210721 17:18:27.546 : INFO : 1
20210721 17:18:27.549 : INFO : b
20210721 17:18:27.549 : INFO : y
20210721 17:18:27.550 : INFO : 2
20210721 17:18:27.552 : INFO : c
20210721 17:18:27.553 : INFO : z
20210721 17:18:27.553 : INFO : 3
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.023_TC_For-in-zip with multiple lists

Starting test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.024_TC_For-in-zip with one variable
20210721 17:18:27.559 : INFO : Length is 3
20210721 17:18:27.560 : INFO : a
20210721 17:18:27.561 : INFO : x
20210721 17:18:27.561 : INFO : 1
20210721 17:18:27.564 : INFO : Length is 3
20210721 17:18:27.566 : INFO : b
20210721 17:18:27.566 : INFO : y
20210721 17:18:27.566 : INFO : 2
20210721 17:18:27.569 : INFO : Length is 3
20210721 17:18:27.570 : INFO : c
20210721 17:18:27.571 : INFO : z
20210721 17:18:27.571 : INFO : 3
Ending test: RobotAutoTest.TestCase.MyTest.My Test Suit2 test for.024_TC_For-in-zip with one variable

Dictionary iteration

*** Variables ***
&{DICT} a=1 b=2 c=3

*** Test Cases ***
Dictionary iteration
FOR ${key} ${value} IN &{DICT}
Log Key is '${key}' and value is '${value}'.
END

Dictionary iteration with enumerate
FOR ${index} ${key} ${value} IN ENUMERATE &{DICT}
Log On round ${index} key is '${key}' and value is '${value}'.
END

Multiple dictionaries and extra items in 'key=value' syntax
&{more} = Create Dictionary e=5 f=6
FOR ${key} ${value} IN &{DICT} d=4 &{more} g=7
Log Key is '${key}' and value is '${value}'.
END



One loop variable FOR ${item} IN &{DICT}
Log Key is '${item}[0]' and value is '${item}[1]'.
END
One loop variable with enumerate
FOR ${item} IN ENUMERATE &{DICT}
Log On round ${item}[0] key is '${item}[1]' and value is '${item}[2]'.
END

Two loop variables with enumerate
FOR ${index} ${item} IN ENUMERATE &{DICT}
Log On round ${index} key is '${item}[0]' and value is '${item}[1]'.
END

除了遍历字典中的名称和值之外,还可以遍历键,然后可能根据键获取值。这种语法要求使用字典作为列表变量:

*** Test Cases ***
One loop variable
FOR ${key} IN @{DICT}
Log Key is '${key}' and value is '${DICT}[${key}]'.
END

请注意

for-in-range或for-in-zip循环不支持字典迭代。

Exiting for loop

通常执行for循环直到所有的循环值都被迭代或者循环中使用的关键字失败。如果需要提前退出循环,可以使用BuiltIn关键字exit For loop和exit For loop If来完成。它们的工作原理类似于Python、Java和许多其他编程语言中的break语句。

Exit For Loop和Exit For Loop If关键字可以直接在For循环内部或循环使用的关键字中使用。在这两种情况下,测试在循环之后继续执行。在for循环之外使用这些关键字是错误的。

*** Test Cases ***
Exit Example
${text} = Set Variable ${EMPTY}
FOR ${var} IN one two
Run Keyword If '${var}' == 'two' Exit For Loop
${text} = Set Variable ${text}${var}
END
Should Be Equal ${text} one

Continuing for loop

除了提前退出for循环外,还可以在执行所有关键字之前继续执行循环的下一个迭代。这可以使用BuiltIn关键字Continue For Loop和Continue For Loop If来完成,就像许多编程语言中的Continue语句一样。

Continue For Loop和Continue For Loop if 关键字可以直接在For循环内部或循环使用的关键字中使用。在这两种情况下,该迭代中的其余关键字都会被跳过,并在下一个迭代中继续执行。如果在最后一次迭代中使用了这些关键字,那么循环之后将继续执行。在for循环之外使用这些关键字是错误的。

*** Test Cases ***
Continue Example
${text} = Set Variable ${EMPTY}
FOR ${var} IN one two three
Continue For Loop If '${var}' == 'two'
${text} = Set Variable ${text}${var}
END
Should Be Equal ${text} onethree

Repeating single keyword

在只需要重复一个关键字的情况下,For循环可能会过多。在这些情况下,通常更容易使用BuiltIn关键字Repeat关键字。这个关键字接受一个关键字以及重复它的次数作为参数。重复关键字的时间可以有一个可选的后缀times或x,以使语法更容易阅读。

*** Test Cases ***
Example
Repeat Keyword 5 Some Keyword arg1 arg2
Repeat Keyword 42 times My Keyword
Repeat Keyword ${var} Another Keyword argument