我从事Java编程已有3年了,但这是我第一次我仍然不了解for循环的基本原理,哦,天哪!
所以我有一个Selenide项目。 Selenide是一个基于SeleniumHQ的网络自动化测试库。
我有一个简单的for循环,循环遍历图像元素列表。
依赖性:
compile group: 'com.codeborne', name: 'selenide', version: '5.2.2'
进口:
import static com.codeborne.selenide.Selenide.$$;
import static com.codeborne.selenide.Selectors.byXpath;
邪恶代码:
final ElementsCollection list = $$(byXpath("//img[@src='original src']"));
for (int i=0; i<list.size(); i++) {
doSth(list.get(i));
}
doSth
方法:
void doSth(SelenideElement element) {
Selenide.executeJavaScript("arguments[0].src = 'new src';", element);
}
当然,以上代码是我正在处理的代码的简单版本,但核心结构仍然存在。
我发现循环计数/迭代次数少于预期,对我而言,它是预期4 与实际2 。
答案 0 :(得分:0)
doSth
方法尝试更改来自参数的src
元素的img
属性。更改之后,img
元素将不再满足XPath。 img
元素在修改后是否满足XPath至关重要,因为Selenide如何检索这些元素。
由于Selenide的XPath选择的元素集合像单个元素对象一样被懒惰地求值,因此集合中的每个元素仅存储元素索引和集合XPath(在Selenide的JavaDoc中提到)。更新集合元素之一的src
属性时,它会导致动态集合大小缩小,从而影响后续的循环迭代。
在阅读ElementsCollection
类的源代码之后,我们将知道ElementsCollection
是具有重写方法的AbstractList
。随着Java for循环的终止条件在每次迭代中得到评估,被覆盖的size()
方法实际上在每次循环迭代后返回一个较小的数字,且递减1
。
由于列表的第一项(0
的索引)已修改其src
,因此每次迭代后,列表1
的大小将缩小n+1
。第n
个元素的位置。我总是可以得到第一项(0
的索引),它实际上给了我下一个项,因为上一个项将不再保留在动态列表中。
[0] = element A
[1] = element B
[2] = element C
[3] = element D
[0] = element B
[1] = element C
[2] = element D
如下修改循环:
final ElementsCollection list = $$(byXpath("//img[@src='original src']"));
final int count = list.size(); // extract to evaluate once only
for (int i=0; i<count; i++) {
doSth(list.get(0)); // change i to 0
}