【问题标题】:Java Selenide - For-Looping ElementsCollection with Modifications During LoopJava Selenide - 在循环期间进行修改的 For-Looping ElementsCollection
【发布时间】:2019-04-02 10:01:13
【问题描述】:

背景

我已经用 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

【问题讨论】:

    标签: java list for-loop selenide


    【解决方案1】:

    根本原因分析

    doSth 方法尝试更改来自参数的img 元素的src 属性。更改后,img 元素将不再满足 XPath。 img 元素在修改后是否满足 XPath 很重要,因为 Selenide 检索元素的方式。

    由于 Selenide 的 XPath 选择的元素集合像单个元素对象一样被延迟评估,所以集合中的每个元素只存储元素索引和集合 XPath(这在 Selenide 的 JavaDoc 中提到)。当集合元素之一的src 属性更新时,它会通过导致动态集合大小缩小来影响后续循环迭代。

    阅读ElementsCollection类的源码后,我们会知道ElementsCollection是一个AbstractList,其方法被覆盖。由于每次迭代都会评估 Java for 循环中的终止条件,因此被覆盖的 size() 方法实际上在每次循环迭代后返回一个较小的数字,并减少 1


    解决方案

    由于列表的第一项(0 的索引)修改了其src,因此列表在每次迭代后将其大小缩小1,第n+1 元素将占据@ 的位置987654336@th 元素。我总是可以得到第一个(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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-04
      • 2011-09-28
      • 2016-10-02
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多