我们都知道RF里只支持for循环,不支持while循环。或者说,不能造出一个死循环(实际上,while循环就是一个带判断条件的死循环)
而且两种通融的办法也做不到
li=[0,1,2]
for i in li:
li.append(i)
# break in some condition
在python里,这样做会导致无限循环。但在RF里,列表在循环前就解析定死,所以对列表的修改并不会影响循环的次数。使用生成器也不能做到
def gen():
while 1: yield 0
for x in gen():
''' do something '''
# break in some condition
因为生成器没有长度,会导致程序只循环一次就结束
后来发现,其实RF里的命令是一条条执行的,只需要把执行的逻辑修改了即可
在底层库robot\running\steprunner.py下,第33行附近的原文
def run_steps(self, steps):
errors = []
for step in steps:
try:
self.run_step(step)
except ExecutionPassed as exception:
''''''
在此处step是关键字,steps是一个循环级别内的全部关键字组成的列表。可以改掉for循环为while循环,采用编号来执行step(关键字)。然后增加一个关键字,让其识别到此关键字时,将编号置为0,即直接跳入循环体的顶部即可。具体改为如下
def run_steps(self, steps):
errors = []
cursor = 0 # the index to execute
keywords = [ str(step).lower() for step in steps ]
while cursor < len(steps):
try:
step = steps[cursor]
if str(step).lower() == "reloop":
assert "exit for loop if" in keywords or "exit for loop" in keywords,\
"both for loop and exit condition are needed"
cursor = 0
continue
cursor += 1
self.run_step(step)
except ExecutionPassed as exception:
''''''
之后在for循环体结束处使用reloop即可造成死循环,且不会取下一个迭代变量
*** Test Cases ***
while循环
${j} set variable ${0}
:for ${i} in range ${1}
\ ${j} set variable ${${j}+1}
\ exit for loop if ${j}==${10}
\ reloop
log many done
可以参考我提交的这个链接
https://github.com/robotframework/robotframework/issues/2721
执行结果如下
Starting test: while循环
20190710 20:20:34.127 TRACE Arguments: [ 0 ]
20190710 20:20:34.127 TRACE Return: 0
20190710 20:20:34.127 INFO ${j} = 0
20190710 20:20:34.127 TRACE Arguments: [ 1 ]
20190710 20:20:34.127 TRACE Return: 1
20190710 20:20:34.128 INFO ${j} = 1
20190710 20:20:34.128 TRACE Arguments: [ '1==10' ]
20190710 20:20:34.128 TRACE Return: None
20190710 20:20:34.129 TRACE Arguments: [ 2 ]
20190710 20:20:34.129 TRACE Return: 2
20190710 20:20:34.129 INFO ${j} = 2
20190710 20:20:34.129 TRACE Arguments: [ '2==10' ]
20190710 20:20:34.129 TRACE Return: None
20190710 20:20:34.130 TRACE Arguments: [ 3 ]
20190710 20:20:34.130 TRACE Return: 3
20190710 20:20:34.130 INFO ${j} = 3
20190710 20:20:34.130 TRACE Arguments: [ '3==10' ]
20190710 20:20:34.130 TRACE Return: None
20190710 20:20:34.131 TRACE Arguments: [ 4 ]
20190710 20:20:34.131 TRACE Return: 4
20190710 20:20:34.131 INFO ${j} = 4
20190710 20:20:34.131 TRACE Arguments: [ '4==10' ]
20190710 20:20:34.131 TRACE Return: None
20190710 20:20:34.132 TRACE Arguments: [ 5 ]
20190710 20:20:34.132 TRACE Return: 5
20190710 20:20:34.132 INFO ${j} = 5
20190710 20:20:34.132 TRACE Arguments: [ '5==10' ]
20190710 20:20:34.132 TRACE Return: None
20190710 20:20:34.133 TRACE Arguments: [ 6 ]
20190710 20:20:34.133 TRACE Return: 6
20190710 20:20:34.133 INFO ${j} = 6
20190710 20:20:34.133 TRACE Arguments: [ '6==10' ]
20190710 20:20:34.134 TRACE Return: None
20190710 20:20:34.134 TRACE Arguments: [ 7 ]
20190710 20:20:34.134 TRACE Return: 7
20190710 20:20:34.134 INFO ${j} = 7
20190710 20:20:34.134 TRACE Arguments: [ '7==10' ]
20190710 20:20:34.135 TRACE Return: None
20190710 20:20:34.135 TRACE Arguments: [ 8 ]
20190710 20:20:34.135 TRACE Return: 8
20190710 20:20:34.135 INFO ${j} = 8
20190710 20:20:34.136 TRACE Arguments: [ '8==10' ]
20190710 20:20:34.136 TRACE Return: None
20190710 20:20:34.136 TRACE Arguments: [ 9 ]
20190710 20:20:34.136 TRACE Return: 9
20190710 20:20:34.137 INFO ${j} = 9
20190710 20:20:34.137 TRACE Arguments: [ '9==10' ]
20190710 20:20:34.137 TRACE Return: None
20190710 20:20:34.138 TRACE Arguments: [ 10 ]
20190710 20:20:34.138 TRACE Return: 10
20190710 20:20:34.138 INFO ${j} = 10
20190710 20:20:34.138 TRACE Arguments: [ '10==10' ]
20190710 20:20:34.139 INFO Exiting for loop altogether.
20190710 20:20:34.139 TRACE Arguments: [ 'done' ]
20190710 20:20:34.139 INFO done
20190710 20:20:34.139 TRACE Return: None