Перейти к содержимому

Selenium WebDriver: полное руководство
онлайн, начало 19 октября
Логи как инструмент тестировщика
онлайн, начало 22 октября
Первый Онлайн ИНститут Тестировщиков
онлайн, начало 15 октября
Тестирование REST API
онлайн, начало 22 октября
Фотография

Наследования


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 9

#1 Isidor2811

Isidor2811

    Новый участник

  • Members
  • Pip
  • 21 сообщений
  • ФИО:Дацюк Олег

Отправлено 07 Июнь 2018 - 14:38

Привет всем. Есть небольшая проблема.

 

У меня есть класс (кусок кода представлен ниже)

public class FirstBP_OrgCreating {

    public WebDriver driver;
    public WebDriverWait wait;
     
    @BeforeClass
    public void setUp(){
        System.setProperty("webdriver.chrome.driver","E:\\chromedriver.exe");
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        wait = new WebDriverWait(driver,20);
        ConfigFile configFile = new ConfigFile();
        configFile.initializeAllField();
    }

    @Test(priority = 0)
    public void cardFill() throws InterruptedException {
        OrgCard orgcard = new OrgCard(driver);
        orgcard.setFieldsOnTheOrgCard();
        PopUpMessage popUpMessage = orgcard.createButtonClick();
        popUpMessage.getLinkFromPopUp();
   }

В этом классе есть 3 метода, которые я хочу использовать в классе №2, один из этих методов cardFill().

 

Код второго класса ниже.

public class OrganizationCabinetReject extends FirstBP_OrgCreating {

    public WebDriver driver;
    public WebDriverWait wait;

    @BeforeClass
    public void setUp(){
        System.setProperty("webdriver.chrome.driver","E:\\chromedriver.exe");
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        wait = new WebDriverWait(driver,20);
        ConfigFile configFile = new ConfigFile();
        configFile.initializeAllField();
    }

    @Test(priority = 1)
    public void cardFill() throws InterruptedException {
        super.cardFill();
    }

В итоге я получаю NullPointerException

 

 
java.lang.NullPointerException
at OrgCard.setFieldsOnTheOrgCard(OrgCard.java:157)
at FirstBP_OrgCreating.cardFill(FirstBP_OrgCreating.java:32)
at OrganizationCabinetReject.cardFill(OrganizationCabinetReject.java:30)
.....
.....
 
где 157 строка это driver.get(ConfigFile.orgCreateUrl);
 
Как сделать это правильно?
 

 

 


  • 0

#2 Little_CJIOH

Little_CJIOH

    Гуру

  • Members
  • PipPipPipPipPipPip
  • 1 176 сообщений
  • ФИО:Власкин Павел
  • Город:Санкт-Петербург


Отправлено 07 Июнь 2018 - 15:45

Во первых, вы не показали код, который бросает эксцепшен.

Во вторых, зачем расширяя существующий класс вы оверрайдите существующие поля и методы абсолютно такими-же?

 

А проблема в том, что вы не различаете одноименные переменные и поля класса. Нужные вам значения вы сохраняете в переменные, экранируя одноименные поля класса, а потом вызываете метод родительского класса, который не имеет доступа к переменным, поэтому обращается к полям класса, а они у нас что? они у нас null, ибо никто ничего им не присвоил.

 

курите: https://javabeginner...s-keyword-java/

 

Хотя... С причиной я не прав. C конкретной причиной.

Скорее проблема в "во вторых". Ибо там вы не оверрайдите, а экранируете.


  • 1

#3 Little_CJIOH

Little_CJIOH

    Гуру

  • Members
  • PipPipPipPipPipPip
  • 1 176 сообщений
  • ФИО:Власкин Павел
  • Город:Санкт-Петербург


Отправлено 07 Июнь 2018 - 16:38

Уберите из класса наследника весь дублирующий код.

То есть остаться должен только cardFill.

 

А лучше, все что хотите дублировать вынесите в base-класс, в котором будут только общие вещи и ни одного теста. И оба класса отнаследуйте от него, а тесты уже в них пишите. А то наследовать before и after это ок, а вот наследовать тесты - плохая практика.


  • 1

#4 Noksa

Noksa

    Активный участник

  • Members
  • PipPip
  • 109 сообщений
  • ФИО:Александр

Отправлено 07 Июнь 2018 - 16:43

Наследованию всегда надо предпочитать композицию, если есть возможность.
И вообще, PageObject в помощь.
  • 0

#5 Isidor2811

Isidor2811

    Новый участник

  • Members
  • Pip
  • 21 сообщений
  • ФИО:Дацюк Олег

Отправлено 07 Июнь 2018 - 17:19

Уберите из класса наследника весь дублирующий код.

То есть остаться должен только cardFill.

 

 

Проблема была все таки в том что я опять указал public WebDriver driver во втором классе. Убрав это объявления переменной все заработало. Спасибо! 

 

 

 

 а вот наследовать тесты - плохая практика.

 

Вот здесь я не понял Вас немного. Каждый методу меня это этап бизнес процесса. Вот cardFill  - это заполнение карточки заявления. В итоге я хочу на одной ветке БП создать этот метод (так как я и сделал в классе FirstBP_OrgCreating) , а дальше наследовать все классы от этого класса, и просто вызывать этот метод. Я не могу понять чем это чревато?

 

 

А лучше, все что хотите дублировать вынесите в base-класс, в котором будут только общие вещи и ни одного теста. И оба класса отнаследуйте от него, а тесты уже в них пишите. 

 

Дело в том что вот этот метод (заполнения карточки заявления будет общий для 10 тестов (10 веток БП)) Что измениться если я вынесу этот метод в base-class и буду наследоваться от него, а не от первого тестового класса? 

 

 

 


  • 0

#6 Noksa

Noksa

    Активный участник

  • Members
  • PipPip
  • 109 сообщений
  • ФИО:Александр

Отправлено 08 Июнь 2018 - 04:38

 

 

 а вот наследовать тесты - плохая практика.

 

Вот здесь я не понял Вас немного. Каждый методу меня это этап бизнес процесса. Вот cardFill  - это заполнение карточки заявления. В итоге я хочу на одной ветке БП создать этот метод (так как я и сделал в классе FirstBP_OrgCreating) , а дальше наследовать все классы от этого класса, и просто вызывать этот метод. Я не могу понять чем это чревато?

 

 

1) Ваши классы нарушают SRP в чистом виде.

Они не выполняют одну задачу, а выполняют две - проверяют какой-то функционал и создают драйвер.

 

Вам нужно вынести всю логику по работе с драйвером в базовый класс для всех тестов. Всё создание драйвера и его уничтожение будет описано в одном месте.

От него и надо будет наследовать классы тестов.

В идеале это должна быть фабрика по созданию нужного драйвера.

В классах тестов не должно быть никакого упоминания о драйвере!

 

Сейчас у вас создание драйвера, во-первых, имеет хардкод в жесткий диск (это вообще жесть полная), во-вторых - предусмотрено создание только хромдрайвера.

И, опять же, дублирование кода создания драйвера, при этом один класс наследует другой... выглядит странным.

 

 

Чем всё это чревато? А тем, что если у вас поменяется что-то в создании драйвера, например, вам будет нужен не хром, а лиса - вам придётся это менять во всех местах.

Эту проблему вообще надо решать другим путём, конечно, это просто как пример.

 

2) Сейчас у вас заполнение карточки является по сути не тестом, а precondition шагом. 

В той реализации, что у вас есть - у вас все тесты будут зависеть по факту от одного теста. Зависимые тесты - это очень плохо. Если ваш первый тест не будет работать - все остальные тоже не будут работать из-за того, что они не могут выполнить precondition шаг.

 

В идеале, нужно уходить от такого рода шагов. Например, путём создания другого precondition шага, который будет в БД приложения записывать нужные данные, а тест уже будет их использовать.

Таким образом, если создание precondition шага в интерфейсе не будет работать - вы сможете проверить другой функционал, минуя его.

А в отдельном одном тесте уже проверять непосредственно cardFill через интерфейс.

 

 

Действия на страницах надо выносить не в базовый класс, а следовать PageObject паттерну, и выносить это в отдельные методы на конкретном pageobject'е. А в самих PageObject применять композицию для избежания дублирования кода.

Допустим, есть общее меню для всех страниц - его нужно выносить в отдельный класс (я их называю блоками) и используя композицию вносить его во все pageobject, где он присутствует.

Таким образом, элементы описанные в этом блоке - будут описаны в одном месте, и при их изменении вам нужно будет исправить их только в одном месте, а не на всех страницах.

 

 

Общее видение PageObject:

 

У вас есть страница Cards. 

Создаёте класс Cards, в нём создаете мелкие методы, которые делают что-то на этой странице.

Потом, если вас это не устраивает - делаете там же общий метод cardFill, который содержит в себе вызовы мелких методов, а не дублирует их логику.

 

 

А в тесте уже используете этот класс и методы из него. Здесь не нужно наследование.


  • 2

#7 Isidor2811

Isidor2811

    Новый участник

  • Members
  • Pip
  • 21 сообщений
  • ФИО:Дацюк Олег

Отправлено 08 Июнь 2018 - 06:38

Вам нужно вынести всю логику по работе с драйвером в базовый класс для всех тестов. Всё создание драйвера и его уничтожение будет описано в одном месте.

От него и надо будет наследовать классы тестов.

 

В идеале это должна быть фабрика по созданию нужного драйвера.

В классах тестов не должно быть никакого упоминания о драйвере!

 

Тут я Вас понял! Именно из за того что я создавал драйвер в каждом классе у меня и наследование не получится. 

Фабрики для создание драйверов мне не нужно - работаем только с chrome, поэтому и указал путь на ЖД. Но уже видел ссылку где это делаеться через maven, пересмотрю потом.

И да то, что в тестах не должно быть упоминание о драйвере только сейчас понял. Но так как я только начинаю работать то для меня понимание этого уже плюс)

 

 

 

2) Сейчас у вас заполнение карточки является по сути не тестом, а precondition шагом. 

В той реализации, что у вас есть - у вас все тесты будут зависеть по факту от одного теста. Зависимые тесты - это очень плохо. Если ваш первый тест не будет работать - все остальные тоже не будут работать из-за того, что они не могут выполнить precondition шаг.

 

В идеале, нужно уходить от такого рода шагов. Например, путём создания другого precondition шага, который будет в БД приложения записывать нужные данные, а тест уже будет их использовать.

Таким образом, если создание precondition шага в интерфейсе не будет работать - вы сможете проверить другой функционал, минуя его.

Дело в том что как бы я не хотел сделать тесты независимыми - этого у меня не получиться. Возьмем для примера заполнения этой карточки. От этого теста зависит выполнение всех последующих. В конце теста есть клик на кнопку, после которого отправляеться на емейл ссылка для дальнейшей работы. Поэтому если даный тест не отработает (ссылка не прийдет) то и последуюющие шаги мне выполнять не нужно. Я не смогу начать выполнять тест с 3 или 4 этапа бизнес процесса. Только в такой последовательности. Поэтому даже при запуске, для того что бы проверить например 8 сетод (завершения БП) мне нужно тест запустить с самого начала. 

Поэтому тут к сожалению я не могу не привязываться к другим тестам.

 

Действия на страницах надо выносить не в базовый класс, а следовать PageObject паттерну, и выносить это в отдельные методы на конкретном pageobject'е. А в самих PageObject применять композицию для избежания дублирования кода.

Допустим, есть общее меню для всех страниц - его нужно выносить в отдельный класс (я их называю блоками) и используя композицию вносить его во все pageobject, где он присутствует.

Таким образом, элементы описанные в этом блоке - будут описаны в одном месте, и при их изменении вам нужно будет исправить их только в одном месте, а не на всех страницах.

 

Общее видение PageObject:

 

У вас есть страница Cards. 

Создаёте класс Cards, в нём создаете мелкие методы, которые делают что-то на этой странице.

Потом, если вас это не устраивает - делаете там же общий метод cardFill, который содержит в себе вызовы мелких методов, а не дублирует их логику.

 

А в тесте уже используете этот класс и методы из него. Здесь не нужно наследование.

 

У сейчас прикреплю код с класса OrgCard, это по сути то что вы говорите:

public class OrgCard {

    WebDriver driver;
    WebDriverWait wait;

    public OrgCard(WebDriver driver){
        this.driver = driver;
        this.wait = wait;
    }

    By orgRegistrationReasonDropBox = By.name("prop_uxp_orgnRegistrationReason");
    By fullOrgNameField = By.name("prop_uxp_orgnName");
    By shortOrgNameField = By.name("prop_uxp_orgnShortName");
    By edrpouField = By.name("prop_uxp_orgnEdrpou");
    By indexField = By.name("prop_uxp_orgnAddressIndex");
    By cityTypeDropBox = By.name("prop_uxp_orgnAddressLocationType");
    By cityNameField = By.name("prop_uxp_orgnAddressLocation");
    By streetTypeDropBox = By.name("prop_uxp_orgnAddressStreetType");
    By streetNameField = By.name("prop_uxp_orgnAddressStreet");
    By houseNumberField = By.name("prop_uxp_orgnAddressHouseNumber");
    By headLastNameField = By.name("prop_uxp_headLastName");
    By headFirstNameField = By.name("prop_uxp_headFirstName");
    By headMiddleNameField = By.name("prop_uxp_headMiddleName");
    By headPhoneField = By.name("prop_uxp_headPhone");
    By headEmailField = By.name("prop_uxp_headEmail");
    By headEdrfou = By.name("prop_uxp_headEdrphou");
    By headCertificate = By.name("file_assoc_uxp_headCertificate_0");
    By responsibleLastNameField = By.name("prop_uxp_responsiblePersonLastName");
    By responsibleFirstNameField = By.name("prop_uxp_responsiblePersonFirstName");
    By responsibleMiddleNameField = By.name("prop_uxp_responsiblePersonMiddleName");
    By responsiblePhoneField = By.name("prop_uxp_responsiblePersonPhone");
    By responsibleEmailField = By.name("prop_uxp_responsiblePersonEmail");
    By respEdrfou = By.name("prop_uxp_responsiblePersonEdrphou");
    By respCertificate = By.name("file_assoc_uxp_responsiblePersonCertificate_0");
    By createButton = By.name("save");
    By linkToHead = By.xpath("//input[@class='popupTextField']");



    public OrgCard selectOrgRegistrationReason(){
        Select selectOrg = new Select(driver.findElement(orgRegistrationReasonDropBox));
        selectOrg.selectByIndex(1);
        return this;
    }
    public OrgCard setFullOrgNameField(String orgName){
        driver.findElement(fullOrgNameField).sendKeys(orgName);
        return this;
    }
    public OrgCard setShortOrgName(String shortOrgName){
        driver.findElement(shortOrgNameField).sendKeys(shortOrgName);
        return this;
    }
    public OrgCard setEdrpou(String edrpou){
        driver.findElement(edrpouField).sendKeys(edrpou);
        return this;
    }
    public OrgCard setIndex(String index){
        driver.findElement(indexField).sendKeys(index);
        return this;
    }
    public OrgCard selectCityType(){
        Select selectCityType = new Select(driver.findElement(cityTypeDropBox));
        selectCityType.selectByIndex(1);
        return this;
    }
    public OrgCard setCityName(String cityName){
        driver.findElement(cityNameField).sendKeys(cityName);
        return this;
    }
    public OrgCard selectStreetType(){
        Select selectStreetType = new Select(driver.findElement(streetTypeDropBox));
        selectStreetType.selectByIndex(1);
        return this;
    }
    public OrgCard setStreetName(String streetName){
        driver.findElement(streetNameField).sendKeys(streetName);
        return this;
    }
    public OrgCard setHouseNumber(String houseNumber){
        driver.findElement(houseNumberField).sendKeys(houseNumber);
        return this;
    }
    public OrgCard setHeadLastName(String headLastName){
        driver.findElement(headLastNameField).sendKeys(headLastName);
        return this;
    }
    public OrgCard setHeadFirstName(String headFirstName){
        driver.findElement(headFirstNameField).sendKeys(headFirstName);
        return this;
    }
    public OrgCard setHeadMiddleName(String headMiddleName){
        driver.findElement(headMiddleNameField).sendKeys(headMiddleName);
        return this;
    }
    public OrgCard setHeadPhone(String headPhone){
        driver.findElement(headPhoneField).sendKeys(headPhone);
        return this;
    }
    public OrgCard setHeadEmail(String headEmail){
        driver.findElement(headEmailField).sendKeys(headEmail);
        return this;
    }
    public OrgCard setHeadEdrfou (String edrfou){
        driver.findElement(headEdrfou).sendKeys(edrfou);
        return this;
    }
    public OrgCard uploadHeadCertificate(String path){
        WebElement upload = driver.findElement(headCertificate);
        upload.sendKeys(path);
        return this;
    }
    public OrgCard setResponsibleLastName(String setResponsibleLast){
        driver.findElement(responsibleLastNameField).sendKeys(setResponsibleLast);
        return this;
    }
    public OrgCard setResponsibleFirstName(String responsibleFirstName){
        driver.findElement(responsibleFirstNameField).sendKeys(responsibleFirstName);
        return this;
    }
    public OrgCard setResponsibleMiddleName(String responsibleMiddleName){
        driver.findElement(responsibleMiddleNameField).sendKeys(responsibleMiddleName);
        return this;
    }
    public OrgCard setResponsiblePhone(String responsiblePhone){
        driver.findElement(responsiblePhoneField).sendKeys(responsiblePhone);
        return this;
    }
    public OrgCard setResponsibleEmail(String responsibleEmail){
        driver.findElement(responsibleEmailField).sendKeys(responsibleEmail);
        return this;
    }
    public OrgCard setRespEdrfou (String edrfou){
        driver.findElement(respEdrfou).sendKeys(edrfou);
        return this;
    }
      public void setFieldsOnTheOrgCard() {
        driver.get(ConfigFile.orgCreateUrl);
        selectOrgRegistrationReason();
        setFullOrgNameField(ConfigFile.orgName);
        setShortOrgName(ConfigFile.orgShortName);
        setEdrpou(ConfigFile.add);
        setIndex(ConfigFile.add);
        selectCityType();
        setCityName(ConfigFile.cityName);
        selectStreetType();
        setStreetName(ConfigFile.streetName);
        setHouseNumber(ConfigFile.add);
        setHeadLastName(ConfigFile.headLastName);
        setHeadFirstName(ConfigFile.headFirstName);
        setHeadMiddleName(ConfigFile.headMiddleName);
        setHeadPhone(ConfigFile.add);
        setHeadEmail(ConfigFile.headEmail);
        setHeadEdrfou(ConfigFile.add);
        uploadHeadCertificate(ConfigFile.headCerteficatePath);
        setResponsibleLastName(ConfigFile.respLastName);
        setResponsibleFirstName(ConfigFile.respFirstName);
        setResponsibleMiddleName(ConfigFile.respMiddleName);
        setResponsiblePhone(ConfigFile.add);
        setResponsibleEmail(ConfigFile.respEmail);
        setRespEdrfou(ConfigFile.add);
        uploadRespCertificate(ConfigFile.respCerteficatePath);
        createButtonClick();
    }

}

Тоесть сначала я ищу все обьекты с которыми я буду работать, потом я создаю методы для каждого этого обьекта(заполнения полей, выбор из селекта) и т.д. А потом создаю метод setFieldsOnTheOrgCard(), после вызова которого у меня будет заполняться вся карточка.

 

На сколько я понял вы предлагаете уже в тестах создать метод напримет cardFill() в нем создать обьект OrgCard  и на нем вызвать метод orgcard.setFieldsOnTheOrgCard(); 

 

Для первого класса у меня такая же реализация. А для других классов  я почему то решил что нужно делать наследования. То есть Вы говорите что нужно и для других классов создавать обьект класса OrgCard  и на нем вызвать метод orgcard.setFieldsOnTheOrgCard(), а не делать наследование

 

 

Спасибо за довольно обширный ответ!


  • 0

#8 Noksa

Noksa

    Активный участник

  • Members
  • PipPip
  • 109 сообщений
  • ФИО:Александр

Отправлено 08 Июнь 2018 - 06:55

Вам нужно вынести всю логику по работе с драйвером в базовый класс для всех тестов. Всё создание драйвера и его уничтожение будет описано в одном месте.

От него и надо будет наследовать классы тестов.

 

В идеале это должна быть фабрика по созданию нужного драйвера.

В классах тестов не должно быть никакого упоминания о драйвере!

 

Тут я Вас понял! Именно из за того что я создавал драйвер в каждом классе у меня и наследование не получится. 

Фабрики для создание драйверов мне не нужно - работаем только с chrome, поэтому и указал путь на ЖД. Но уже видел ссылку где это делаеться через maven, пересмотрю потом.

И да то, что в тестах не должно быть упоминание о драйвере только сейчас понял. Но так как я только начинаю работать то для меня понимание этого уже плюс)

 

 

Мыслите шире. Или даже так - мыслите интерфейсами. Это позволит вам писать легкоизменяемый код, который при этом не повлияет на работоспособность другого кода, который его использует.

 

Сейчас не нужно - а завтра будет нужно. Заказчики люди непостоянные и требования у них могут меняться каждый день :)

 

Лучше сразу предусмотреть возможность создания любого драйвера, чтобы потом не пришлось строить костыли.

 

Хороший вариант, это параметризация запуска тестов. При запуске передавать параметр - какой браузер использовать.

Таким образом, вы одновременно, например на разных машинах, сможете запустить все тесты на разных браузерах.

 

 

Дело в том что как бы я не хотел сделать тесты независимыми - этого у меня не получиться. Возьмем для примера заполнения этой карточки. От этого теста зависит выполнение всех последующих. В конце теста есть клик на кнопку, после которого отправляеться на емейл ссылка для дальнейшей работы. Поэтому если даный тест не отработает (ссылка не прийдет) то и последуюющие шаги мне выполнять не нужно. Я не смогу начать выполнять тест с 3 или 4 этапа бизнес процесса. Только в такой последовательности. Поэтому даже при запуске, для того что бы проверить например 8 сетод (завершения БП) мне нужно тест запустить с самого начала. 

 

Можно использовать API, или БД, необязательно создавать тестовые данные через интерфейс. Это быстрее и надежнее.
 
Но, если вы прям уж очень хотите завязываться на интерфейс - в таком случае нужно скипать все тесты, которые не будут выполняться без этого шага, чтобы сэкономить время. Ибо запускать их смысла нет. Ну и указывать причину, почему скипнуты.
 

 

 

На сколько я понял вы предлагаете уже в тестах создать метод напримет cardFill() в нем создать обьект OrgCard  и на нем вызвать метод orgcard.setFieldsOnTheOrgCard(); 

 

Не-не, ни в коем разе.
Да, у вас вполне себе pageobject.
Тесты не должны создавать методы, они должны только использовать их. Иначе будет каша.
 
 

 

 

Для первого класса у меня такая же реализация. А для других классов  я почему то решил что нужно делать наследования. То есть Вы говорите что нужно и для других классов создавать обьект класса OrgCard  и на нем вызвать метод orgcard.setFieldsOnTheOrgCard(), а не делать наследование

 

Вы путаете тестовые классы и PageObject классы.

Тестовые классы должны использовать экземпляры pageobject классов.

Сам тестовый класс не должен знать ничего о другом тестовом классе, он должен только наследовать базовый тестовый класс для всех тестовых классов, в котором реализована общая логика для всех тестовых классов (методы создания драйвера, уничтожения драйвера, что-то ещё)

 

Так же как и PageObject классы - могут наследовать какой-то базовый для них всех класс, в котором например:

1) Будет конструктор с PageFactory с кастомным декоратором, чтобы не писать его каждый раз в каждом наследнике.

2) Какие-то общие для всех страниц методы и так далее...

 

 

PS: 

Вынесите в OrgCard всю логику, ведь она относится непосредственно к этой странице:

public string fillCard()
{    
    this.setFieldsOnTheOrgCard();
    PopUpMessage popUpMessage = this.createButtonClick();
    return popUpMessage.getLinkFromPopUp();
} 

 

А в тестах используйте в первой строке:

new OrgCard(driver).fillCard()

и никакого наследования тестами других тестов.


  • 2

#9 Noksa

Noksa

    Активный участник

  • Members
  • PipPip
  • 109 сообщений
  • ФИО:Александр

Отправлено 08 Июнь 2018 - 07:12

Так же, я бы вам советовал сразу писать такую архитектуру, в которой не требуется в конструктор страницы передавать драйвер.

Т.е, в конструктор страницы вообще ничего не следует передавать.

 

Как вариант, использовать статичный драйвер в контейнере ThreadLocal<>.

 

Это моё субъективное мнение.

 

 

Пример с C#, на страницах не требуется объявлять конструктор, он вызывается из базового класса.

При этом все прекрасно бегает в параллельных потоках.

public class NewsPage : BasePage
    {
      ....
    }


public abstract class BasePage
    {
     ...

     protected BasePage()
        {
            Elements.Clear();
            ElementsInBlocks.Clear();
            PageFactory.InitElements(DriverManager.Driver, this, new AFieldDecorator());
        }

  • 1

#10 Isidor2811

Isidor2811

    Новый участник

  • Members
  • Pip
  • 21 сообщений
  • ФИО:Дацюк Олег

Отправлено 08 Июнь 2018 - 13:43

 

Так же, я бы вам советовал сразу писать такую архитектуру, в которой не требуется в конструктор страницы передавать драйвер.

Т.е, в конструктор страницы вообще ничего не следует передавать.

 

Как вариант, использовать статичный драйвер в контейнере ThreadLocal<>.

 

Это моё субъективное мнение.

 

 

Пример с C#, на страницах не требуется объявлять конструктор, он вызывается из базового класса.

При этом все прекрасно бегает в параллельных потоках.

public class NewsPage : BasePage
    {
      ....
    }


public abstract class BasePage
    {
     ...

     protected BasePage()
        {
            Elements.Clear();
            ElementsInBlocks.Clear();
            PageFactory.InitElements(DriverManager.Driver, this, new AFieldDecorator());
        }

Еще раз спасибо за советы. Начал гуглить и нашел вот что https://www.youtube....h?v=zCjNOIp7p3c . Думаю многим пригодиться, так как тут есть 80% ваших советов. Буду разбираться :pardon:


  • 0


Программирование на С# для тестировщиков
онлайн, начало 28 сентября
Автоматизатор мобильных приложений
онлайн, начало 3 октября
Selenium WebDriver: полное руководство
онлайн, начало 19 октября
Программирование на Python для тестировщиков
онлайн, начало 26 октября



Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных

Яндекс.Метрика
Реклама на портале