Selenium @FindBy vs driver.findElement()

Почему я должен использовать @FindBy vs driver.findElement()?

@FindBy заставляет меня переместить все мои переменные на уровень класса (когда большинство из них должны быть только на уровне метода). Единственное, что мне кажется, это купить меня, я могу вызвать PageFactory.initElements(), которая обрабатывает ленивую инициализацию для меня.

Что мне не хватает?

Ответ 1

Грубо говоря, @FindBy - это просто альтернативный способ нахождения элементов ( "обычный способ" есть driver.findElement(), как вы сказали).

Большое преимущество этой аннотации не само. Он лучше используется для поддержки шаблона PageObject.

В нескольких словах шаблон PageObject сообщает создать класс для каждой страницы системы, которую вы пытаетесь использовать /test.

Итак, вместо того, чтобы иметь (обычный driver.findElement() код):

public class TestClass {
    public void testSearch() {
        WebDriver driver = new HtmlUnitDriver();
        driver.get("http://www.google.com/");
        Element searchBox = driver.findElement(By.name("q"));
        searchBox.sendKeys("stringToSearch");
        searchBox.submit();
        // some assertions here
    }
} 

Вы определяете класс для страницы (с аннотацией @FindBy для используемых элементов):

public class GooglePage {
    @FindBy(how = How.NAME, using = "q")
    private WebElement searchBox;
    public void searchFor(String text) {
        searchBox.sendKeys(text);
        searchBox.submit();
    }
}

И используйте его как:

public class TestClass {
    public void testSearch() {
        WebDriver driver = new HtmlUnitDriver();
        driver.get("http://www.google.com/");
        GooglePage page = PageFactory.initElements(driver, GooglePage.class);
        page.searchFor("stringToSearch");
        // some assertions here
    }
} 

Теперь я знаю, что сначала это может показаться многословным, но просто дайте ему мгновение и подумайте о том, что для этой страницы есть несколько тестов. Что, если изменится имя searchBox? (От name "q" до id, скажем query?)

В каком коде было бы больше изменений, чтобы заставить его работать снова? Единица с или без объектов страницы (и @FindBy)? Если страница сильно меняет свою структуру, в каком коде обслуживание будет проще?

Есть и другие преимущества, такие как дополнительные аннотации, например:

@FindBy(name = "q")
@CacheLookup
private WebElement searchBox;

То, что @CacheLookup вызывает поиск элемента, происходит только один раз. После этого он будет кэшироваться в переменной и доступен гораздо быстрее.

Надеюсь, это поможет. Для получения дополнительной информации обязательно проверьте PageFactory и шаблон PageObject.

Ответ 2

Мне не нравятся аннотации @FindBy, потому что тогда IntelliJ больше не определяет, используется ли эта переменная, из-за этого становится все труднее очистить.

Ответ 3

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class CommonPageForStudent {

    @FindBy(name="usname")
    private WebElement Studentusername;
    @FindBy(name="pass")
    private WebElement Studentpassword;
    @FindBy(xpath="//button[@type='submit']")
    private WebElement StudentLetmein;
    @FindBy(id="logoutLink")
    private WebElement StudentlogoutLnk;
    public  void loginToStudent(String username , String password ){
        Studentusername.sendKeys(username);
        Studentpassword.sendKeys(password);
        StudentLetmein.click();

       }

    //when you call this methods from another class write this 2 line code that class
    //CommonPageForStudent page = PageFactory.initElements(driver,       CommonPageForStudent.class);
    // page.loginToStudent("","");

    public void logOut(){
        StudentlogoutLnk.click();
    }
    //page.logOut(); method call

}`

Ответ 4

Одним из преимуществ использования Page Factory является то, что он может избежать StaleElementException. Пожалуйста, смотрите ссылку ниже:

Как объектная модель страницы решает StaleElementReferenceException?

Выдержки из вышеуказанной ссылки:

Вы увидите, что программы работают нормально, когда мы используем шаблон дизайна объекта страницы. Вы никогда не получите исключение по ссылкам на устаревшие элементы. Когда мы используем аннотацию FindBy в POM, веб-драйвер находит элемент и обновляет ссылку каждый раз перед выполнением каких-либо действий с ним. Вы можете использовать веб-элемент без перемещения в любое место. Это главное преимущество использования объектной модели страницы.


Как бороться и избегать несвежих элементов.

Выдержки из вышеуказанной ссылки:

Как бороться и избегать несвежих элементов

Есть много способов справиться с исключением устаревших элементов в Интернете. Здесь я собрал те, которые лично я считаю наиболее полезными.

Хорошей практикой является использование аннотации @FindBy из-за отложенной инициализации. Таким образом, элементы будут инициализированы непосредственно перед фактическим использованием. Пример: @FindBy (xpath = "someXpath") public WebElement someElement;

Используйте методы ожидания для JavaScript, Ajax, Jquery и т.д. Это решит "условие гонки", которое вызывает это исключение.

Ответ 5

Проще говоря, @FindBy и driver.findElement() - это разные подходы к поиску элементов с помощью различных стратегий локатора.

При использовании PageFactory мы можем использовать тип аннотации FindBy. Аннотации FindBy помогают нам удалить стандартный код, который мы обычно используем в форме findElement() и findElements() при поиске элементов.

В качестве примера:

WebElement element = driver.findElement(By.name("q"));
element.click();

будет выглядеть так:

element.click();

Вы можете найти комментарии @Simon Stewart по той же теме в обсуждении. Как использовать явное ожидание с полями PageFactory и шаблоном PageObject.