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

Фотография

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


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 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 515 сообщений
  • ФИО:Власкин Павел
  • Город:Санкт-Петербург


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

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

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

 

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

 

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

 

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

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


  • 1

#3 Little_CJIOH

Little_CJIOH

    Профессионал

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


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

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

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

 

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


  • 1

#4 Noksa

Noksa

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

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

Отправлено 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
  • 117 сообщений
  • ФИО:Александр

Отправлено 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
  • 117 сообщений
  • ФИО:Александр

Отправлено 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
  • 117 сообщений
  • ФИО:Александр

Отправлено 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


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

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