robotframework-循环

1,724 阅读9分钟

在自动化测试种,重复执行相同的动作多次是一个相当常见的操作,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