代码之家  ›  专栏  ›  技术社区  ›  Abhijeet Vaikar

如何避免在同一个web元素上调用多个driver.findElement?

  •  0
  • Abhijeet Vaikar  · 技术社区  · 12 年前

    我将PageObject模式用于我的selenium webdriver+TestNG框架。
    在我的pageObject类中,我有多个方法,我使用driver.findElement来查找同一页面上的同一个web元素。
    例如:

     public class HomePage extends BasePage {
            private WebElement searchField;
            private String searchFieldLocator;
    
    
            HomePage(WebDriver driverFromTest, CustomLogger loggerFromTest,
                    HashMap<String, String> testDataMapFromTest)
            {
                super(driverFromTest, loggerFromTest, testDataMapFromTest);
                searchFieldLocator = testDataMap.get("searchFieldLocator");
    
            }
    
    
            public void method1()
          {
    
            searchField = driver.findElement(By.cssSelector(searchFieldLocator));
            searchField.sendKeys("foo");
    
          }
    
    
          public void method2()
          {
             searchField = driver.findElement(By.cssSelector(searchFieldLocator));
             searchField.sendKeys("bar");
          }
    



    我的问题是:
    1.如何避免在同一WebElement变量上多次使用driver.findElement。我想要一种方法,一旦我找到web元素,我就只在任何其他方法中使用该变量,而不使用driver.findElement。我读过关于PageFactory的文章,在那里你可以使用@FindBy(how=how.NAME,using=“locatorstring”)和@CacheLookup注释。这是我需要的吗?CacheLookup是否只使用driver.findElement一次并重新使用引用?

    2.其次,当你对同一个web元素执行driver.findElements太多次时,是否会占用内存?这是我不需要担心的微观优化吗?

    我想了一种方法来避免在同一个web元素上执行driver.findElement,方法如下:

     protected WebElement getWebElement(By by, String elementName) {
            WebElement element;
    
            if(webElementMap.get(elementName)==null)
            {
               element = driver.findElement(by);
               webElementMap.put(elementName, element);
            }
            else
                element = webElementMap.get(elementName);
    
            return element;
    
        }
    

    这样做对吗?

    2 回复  |  直到 12 年前
        1
  •  1
  •   Ardesco Dmitri T    12 年前

    @CacheLookup只使用了一次driver.findElement,并重新使用了该引用。

    请注意,尽管您可能会开始遇到StaleElementReferenceException

        2
  •  1
  •   Archmede    7 年前

    使用网格提供程序(如Saucelabs)时,多次调用可能会出现问题。

    每个Webdriver命令都会产生一个API调用,因此以下命令将进行两个API调用;

    searchField = driver.findElement(By.cssSelector(searchFieldLocator));
    searchField.sendKeys("foo");
    

    对网格的请求将比使用特定驱动程序(如ChromeDriver)慢很多,因此在编写可能使用网格的测试时必须考虑这一点。缓存对象就是实现这一点的方法。

    但是,如果缓存对象,则很可能会命中 StaleObject 问题,所以你引用肯尼·罗杰斯的话;

    “你必须知道什么时候该抱着,什么时候该折叠”

    我个人远离 @FindBy @CacheLookup 注释,因为我想控制缓存策略