我們都知道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