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

Фотография

Грамотное построение фреймверка дл тестирование WEB Forms

WEB Forms selenium webdriver

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

#1 Dmitriy_BOL

Dmitriy_BOL

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

  • Members
  • Pip
  • 29 сообщений


Отправлено 20 июня 2016 - 10:10

Добрый день всем.

Решил взяться за новый проект. Суть его в следующем:

Есть сайт написанный на Web Forms. Этот сайт ищет данные в БД. Навигация у этого сайта организована на основании двух фреймов, фрейм "навигации" и фрейм "рабочей области". Изначально при загрузке сайта в "рабочей области" появляется главная форма. В ней предложен выбор раздела для пользователя.После выбора раздела в фрейме "навигация" отображается иерархическое "дерево" с разделами, подразделами и ссылками на странице поиска. После выбора выбора ссылки на страницы поиска во фрейме "навигация", она подгружается во фрейм "рабочая область". После всего этого на странице можно производить поиск. Для того что бы  перейти  на  другую  страницу, надо вернуться во фрейм "навигация" и выбрать новую страницу.

 

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

 

Подумав, я решил сделать следующим образом: создать проtкт MAVEN, в проекте создать класс FrameManagement отвечающий за навигацию(переключение между фреймами, нажатие кнопок и ссылок), класс SearchPage(отвечающий за действие с элементами на странице поиска и манипулирование с  результатами поиска), и из всего этого воять фрейверк для дальнейшего тестирования таких решений.

 

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;
//Данный класс будет отвечать за  навигацию по фреймам.
public class FrameManagement {

private WebDriver driver;
public FrameManagement(){
ProfilesIni profiles = new ProfilesIni();
FirefoxProfile profileFirefox = profiles.getProfile("TestQA");
this.driver = new FirefoxDriver(profileFirefox);
}
   
    public static void goToFrame(){}

    public static void goToParentFrame(){}

    public static void ManagementMainFrame(){}
    
    public void ClickButton(){}
}
**********************************************************
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
//Данный класс отвечает за страницу поиска, и возможные действия с этим объектом
public class SearchPage {
public WebDriver driver;
public SearchPage( WebDriver driver){}
public void ClickLink(){}
public void GetInformationObjectCount(){}
public void setMainSettingsField(String s, String input){}
public void setMainSettingsRadioBox(){}
public void setSystemSettingCheckBox(){}
public void Result(){}
}
*********************************************************
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class RegionSearchTest {
@Before
public void setUp(){ //метод открывающий браузер }
@Test
public void Search(){ //тело самого теста }
@After
public void close(){ //метод закрывающий браузер } }
 

 

 
На "void" не обращайте внимание, так как я поставил его для того что бы IDE не ругалась.
 
Вроде как  структура нехитрая, но тут я  попал в ступор. Я не могу не как додумать как правильно между всем этим передавать WebDriver. Как я понял, метод вызова открытия браузера надо реализовывать в классе FrameManagement, так как он по логике своей отвечает за полную координацию выполнение тестов. А каким тогда способом его передать классу SearchPage, если класс RegionSearchTest будет наследовать методы от класса SearchPage.
 
Может кто то уже  сталкивался с построением фреймверков для тестирования именно таких фреймовых структур?

  • 0

#2 serjb9

serjb9

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

  • Members
  • Pip
  • 68 сообщений

Отправлено 20 июня 2016 - 11:22

А зачем вам между всем этим мешать драйвер?

Создайте отдельный класс для инициализации драйвера, создайте WebDriver static поле и загрузите туда нужный драйвер. Он будет доступен отовсюду.


  • 0

#3 Dmitriy_BOL

Dmitriy_BOL

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

  • Members
  • Pip
  • 29 сообщений


Отправлено 20 июня 2016 - 11:48

я не зря написал "грамотное построение фреймверка",  способ предложенный тобой  хорош но равносилен тому, как тебя бы позвали на ужин и вместо того что бы есть через рот, разрезали брюхо и  туда положили еду. Есть такие  понятия как инкапсуляция и полиморфизм и при построении какого либо фремверка для чего либо понятиями ООП брезговать не стоит, ибо если кто то кроме тебя будет использовать  сделанное  тобой  решение, может наломать много "дров" очень много.


  • 0

#4 serjb9

serjb9

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

  • Members
  • Pip
  • 68 сообщений

Отправлено 20 июня 2016 - 12:22

Ну так и используйте фреймменеджмент как суперкласс, вариантов то масса на самом деле.

В базовом конструкторе у вас уже есть инициализация, так что почему нет.

Недавно смотрел доклад Николая  , там на 27 минуте.


  • 0

#5 TatyanaV

TatyanaV

    Опытный участник

  • Members
  • PipPipPipPip
  • 388 сообщений
  • ФИО:Воробьева Татьяна


Отправлено 20 июня 2016 - 13:00

У меня похожая структура. Тоже долго думала, как же это сделать.
В результате (в т.ч. после советов Алексея Баранцева), пришла к такому варианту.
 
Есть хелпер по навигации (наследуемый от сохраненного после треннингов DriverBasedHelper, в котором уже есть ссылки и на WebDriver, и на PageManager, и т.д.).
Внутри этого хелпера - методы открытия пунктов меню (например, openSomeSpecialPage).
При чем, если этот пункт вложен в другой - сначала будет вызван вызов пункта-родителя (например, openSpecialMenuFolder), и так вплоть до корня дерева.
В результате, я просто пишу какой пункт открыть, и система уже сама по этим вложенным методам прокликивает нужные папочки, чтобы в дереве стал доступен нужный мне пункт (ну и кликает по нему самому, естественно, в самом конце). 
Вся эта часть по умолчанию работает с фреймом навигации, без дополнительных надстроек вроде ФреймМенеджеров.
После открытия менюшки - уже просто некая "страница". Все страницы из этого интерфейса - по умолчанию работают с фреймом содержимого, опять таки без дополнительных надстроек вроде ФреймМенеджеров.
 
Соответственно, если мне нужно из текущей "страницы" куда-то перейти, я просто вызываю навигационный хелпер и указываю ему, какая страница мне нужна. Он уже сам переходит во фрейм навигации и прокликивает нужные менюшки. А я могу начинать работать с новой страницей, не переживая про фреймы, т.к. страница и так сама знает, что ей надо смотреть во фрейм содержимого.

  • 0

#6 elvis

elvis

    Постоянный участник

  • Members
  • PipPipPip
  • 189 сообщений
  • Город:Tallinn


Отправлено 20 июня 2016 - 13:18

Если класс отвечает за навигацию по фреймам, то зачем ему отвечать за инициализацию драйвера? А ежели тестировать будете с разными браузерами? Фреймворк должен быть достаточно абстрактен. Пусть за инициализацию драйвера отвечает отдельный класс, который читает некий system property и если тот null, то устанавливает драйвер например на FirefoxDriver(), в противном случае на нужное значение и хранит драйвер в static поле.


  • 0

#7 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 20 июня 2016 - 13:37

Почему все прицепились к static Webdriver. Не надо никаких статиков !

 

И по поводу навигации по дереву.

Просто отдельный класс, который будет за это отвечать.

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


  • 0

#8 TatyanaV

TatyanaV

    Опытный участник

  • Members
  • PipPipPipPip
  • 388 сообщений
  • ФИО:Воробьева Татьяна


Отправлено 20 июня 2016 - 13:41

Почему все прицепились к static Webdriver. Не надо никаких статиков !

 

И по поводу навигации по дереву.

Просто отдельный класс, который будет за это отвечать.

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

Почему "либо"? 

Это одно и тоже по сути :)

папка1

|----папка2

     |----папка3

          |----нужныйпункт

 

openFolder1() = клик по "папка1"

openFolder2() = openFolder1() + клик по "папка2"

openFolder3() = openFolder2() + клик по "папка3"

openMenuItem() = openFolder3() + клик по "нужныйпункт"

Можно их не вызывать внутри друг дружки, но каждый раз полный путь вручную прописывать.

А можно вызывать, как у меня указано и в тесте просто указывать openMenuItem().

 

Да кстати, методы с "Folder" возвращают сам хелпер (return this), методы открытия конкретных пунктов меню - возвращают соответствующие страницы.


  • 0

#9 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 20 июня 2016 - 13:42

 

Почему все прицепились к static Webdriver. Не надо никаких статиков !

 

И по поводу навигации по дереву.

Просто отдельный класс, который будет за это отвечать.

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

Почему "либо"? 

Это одно и тоже по сути :)

папка1

|----папка2

|--------папка3

|------------нужныйпункт

 

|--------папка3

 

 

Да, это одно и тоже просто способы разные. И тот и другой допустим


  • 0

#10 elvis

elvis

    Постоянный участник

  • Members
  • PipPipPip
  • 189 сообщений
  • Город:Tallinn


Отправлено 20 июня 2016 - 14:07

Почему все прицепились к static Webdriver. Не надо никаких статиков !

 

И по поводу навигации по дереву.

Просто отдельный класс, который будет за это отвечать.

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

Ну не надо так не надо. Можно и без статиков getWebdriver()


  • 0

#11 Dmitriy_BOL

Dmitriy_BOL

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

  • Members
  • Pip
  • 29 сообщений


Отправлено 21 июня 2016 - 06:35

Разрешил проблему следующим  способом.

Создал класc Page, в котором объявил вебдрайвер приветом, добавил конструктор для установки драйвера при создании страницы. В классе управления страницей создал объект Page, и создал конструктор для класса управления  через который передаю объекту Page вебдрайвер. С помощью такого подхода я  добился того, что драйвер закрыт со всех сторон и  его можно вызвать только  через класс управление, что исключает неправильное обращение с  фреймверком. 

 

Сам код(в дальнейшем  когда я  решу  все проблемы и пересоберу в MAVEN поделюсь готовым решением):

Реализация класса страницы.

import org.openqa.selenium.WebDriver;

public class Page {

    private WebDriver driver;

    public Page( WebDriver driver){
        this.driver= driver;
    }

    public WebDriver getPageDriver() {
        return this.driver;
    }
    
}

Реализация класса управления.

import org.openqa.selenium.WebDriver;

public class FrameManagement {
    private Page Page;
    public FrameManagement(WebDriver driver){
        this.Page = new Page(driver);
    }

    private WebDriver getPage(){
      return  this.Page.getPageDriver();
    }

    public void getPageToUrl(String URL){
        getPage().get("s");
    }
}

Реализация класса самого теста

import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;


public class RegionSearchTest {



    public static void main( String[] args){
        ProfilesIni profiles = new ProfilesIni();
        FirefoxProfile profileFirefox = profiles.getProfile("TestQA");
        FrameManagement mgr  = new FrameManagement(new FirefoxDriver(profileFirefox));
        mgr.getPageToUrl("http://www.yandex.ru");
    }

}

Вот такой  вот  способ, но от не доработан.

Проблема в  том что при такой  реализации построения фреймверка проект компилируются и запускается, открывается браузер с пустой  страницей без указанного мной URL.  

Стек ошибки:

"C:\Program Files\Java\jdk1.8.0_91\bin\java" -Didea.launcher.port=7541 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_91\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_91\jre\lib\rt.jar;C:\Users\****\Dropbox\test\out\production\test;C:\Users\****\Dropbox\selenium-server-standalone-2.53.0.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.1\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain RegionSearchTest
Exception in thread "main" org.openqa.selenium.WebDriverException: Target URL s is not well-formed.
Command duration or timeout: 167 milliseconds
Build info: version: '2.53.0', revision: '35ae25b', time: '2016-03-15 17:00:58'
System info: host: '____________', ip: '***.168.0.121', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_91'
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{applicationCacheEnabled=true, rotatable=false, handlesAlerts=true, databaseEnabled=true, version=46.0, platform=WINDOWS, nativeEvents=false, acceptSslCerts=true, webStorageEnabled=true, locationContextEnabled=true, browserName=firefox, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: 080544f7-80d2-4ea7-86db-45c2fe1d24be
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206)
	at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158)
	at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:678)
	at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:316)
	at FrameManagement.getPageToUrl(FrameManagement.java:17)
	at RegionSearchTest.main(RegionSearchTest.java:17)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.openqa.selenium.WebDriverException: Target URL s is not well-formed.
Build info: version: '2.53.0', revision: '35ae25b', time: '2016-03-15 17:00:58'
System info: host: '___________', ip: '***.168.0.121', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_91'
Driver info: driver.version: unknown
	at <anonymous class>.FirefoxDriver.prototype.get(file:///C:/Users/*******~1/AppData/Local/Temp/anonymous5143472155413947786webdriver-profile/extensions/fxdriver@googlecode.com/components/driver-component.js:10636)
	at <anonymous class>.DelayedCommand.prototype.executeInternal_/h(file:///C:/Users/*******~1/AppData/Local/Temp/anonymous5143472155413947786webdriver-profile/extensions/fxdriver@googlecode.com/components/command-processor.js:12661)
	at <anonymous class>.DelayedCommand.prototype.executeInternal_(file:///C:/Users/*******~1/AppData/Local/Temp/anonymous5143472155413947786webdriver-profile/extensions/fxdriver@googlecode.com/components/command-processor.js:12666)
	at <anonymous class>.DelayedCommand.prototype.execute/<(file:///C:/Users/*******~1/AppData/Local/Temp/anonymous5143472155413947786webdriver-profile/extensions/fxdriver@googlecode.com/components/command-processor.js:12608)

Process finished with exit code 1

Как видно из ошибки проблема с  передаваемым URL(звездочки и подчеркивания добавлены на  правах конфиденциальности). Я так понял что в  процессе решение данной задачи я потерял управление над драйвером(если я  правильно  понял), возможно я что то упустил из понятий ООП( тестеровщики в  них не  очень хорошо разбираются :smile:  :smile: ). 

Кто то может  подсказать, что я  упустил?


  • 0

#12 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 21 июня 2016 - 06:59

public void getPageToUrl(String URL){
getPage().get("s");
}

Передавай урл сюда, а не "s"


  • 2

#13 elvis

elvis

    Постоянный участник

  • Members
  • PipPipPip
  • 189 сообщений
  • Город:Tallinn


Отправлено 21 июня 2016 - 08:11

как же я рад, что перешёл в своё время на selenide :D Теперь не надо таскать с собой повсюду этот инстанс драйвера.


  • 0



Темы с аналогичным тегами WEB Forms, selenium, webdriver

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

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