2016-12-16 5 views
0

У меня есть набор тестов, который в настоящее время работает в разных средах разработки. Недавно была завершена полная переработка приложения &, развернутого в новой среде.Обработка среды с аналогичной логикой страницы, но разные локаторы

Приложение выглядит & действует почти идентично. Логика страниц более или менее одинакова. Большая разница в том, что переписывание HTML сделало мои локаторы бесполезными. Я не уверен, как обращаться с локаторами для этой новой среды и в то же время придерживаться объектной модели страницы.

Модель объектной модели заявляет, что вся логика страницы должна храниться в соответствующем классе объектов страницы. Я предполагаю, что это включает в себя локаторы.

Следуя этой стратегии, я оставил бы меня с раздутым классом класса объектов, полным дубликатов локаторов. Существуют ли рекомендуемые рекомендации или чистые решения для борьбы с этой проблемой?

Возможные решения я могу думать о том, являются:

  1. Создание отдельных файлов локатора для каждой среды и удалить их из класса страницы объекта.
  2. Создание дубликатов или схожими именами локаторы в текущей странице объекта класса
  3. Создание отдельных объектов страниц для новой среды

Может anyody комментарий от того или нет звук хорошо эти решения? Или предложите альтернативные предложения?

+0

Вы используете аннотацию «FindBy» в классах PageObject? Или вы используете findElement из кода? – Grasshopper

+0

Im используя @FindBy аннотации – Cathal

ответ

3

Определенно переместите локаторы вне класса pageobject в два разных класса: один для старых локаторов и один для новых локаторов. Используйте публичную статическую финальную строку для каждого локатора. Проблема, которую вы собираетесь иметь, заключается в том, что значения аннотации Java требуют постоянного выражения, поэтому вы не можете использовать метод отправки другого локатора в FindBy. Но вы можете использовать тернарный оператор для создания постоянного выражения.

Ниже я добавил код, который на основе глобального флага нажимает на другую кнопку из одного WebElement, но локатор изменяется выражением на значении «using» аннотации FindBy. Вы можете установить значение глобального флага при запуске, когда вы инициализируете драйвер из файла свойств.

Это то, что вам нужно будет включить в FindBy и локаторы, отправленные findElement() - using = GlobalFlag.devEnv? NewLocators.newLocxpath: OldLocators.newLocxpath. Это будет боль, чтобы скопировать пасту повсюду.

Вы можете попробовать код, поскольку веб-сайт является общедоступным.

class CartConstant { 
    //Old locators 
    public static final String cartxpath = "//span[.='Cart']"; 
} 

class AccountConstant { 
    //New locators 
    public static final String accxpath = "//span[.='Account']"; 
} 

class GlobalFlag { 
    //Initialize this at the start 
    public static final boolean devEnv = true; 
} 

public class ChangeAnnotation { 
    //Change this in the code to include the choice 
    @FindBy(how=How.XPATH, using=GlobalFlag.devEnv ? AccountConstant.accxpath : CartConstant.cartxpath) 
    private WebElement butt; 

    @Test 
    public void demoSQA() throws InterruptedException { 

     System.setProperty("webdriver.chrome.driver", "E:/Software Testing/Selenium/Jars/chromedriver.exe"); 
     ChromeOptions chop = new ChromeOptions(); 
     chop.addArguments("test-type"); 
     chop.addArguments("start-maximized"); 
     WebDriver driver = new ChromeDriver(chop); 

     driver.get("http://store.demoqa.com/products-page/product-category/imacs/");   
     Thread.sleep(3000);  
     PageFactory.initElements(driver, this);  
     butt.click();    
    } 
} 
+0

Привет, Кузнечик, спасибо за предложение. Я думаю, что вы на правильном пути со своим предложением. Оптимальное решение, вероятно, связано с созданием пользовательского ElementLoactorFactory, к сожалению, это не то, что я полностью понимаю, как это сделать. Я закончил переписывание объекта страницы целиком, потому что разница в логике страниц была больше, чем я первоначально думал. Тем не менее, теперь я остался с достаточным количеством дублированного кода. – Cathal

+0

Не большая задача написать собственный код, так как он просто расширяет классы по умолчанию в коде Selenium.Я думаю, вам также потребуется добавить новый параметр в свой собственный класс FindBy, расширяющий существующий. Иначе это испортит существующее «использование». Извлеките свой дублированный код в базовый класс или какую-нибудь другую стратегию, уверен, что он придет и укусит вас на более позднем этапе с дублированием, если у вас есть растущий проект. – Grasshopper

0

Вот как мне удалось преодолеть это.

Я сохранил разные файлы свойств элементов для разных сред.

Допустит, среда A, B В моем проекте я держу два собственности файлов с именем Elements_A.properties и Elements_B.properties Этих файлов свойства имеют все элементы страницы. Если один элемент отличается от другого, это не будет проблемой, поскольку при запуске скрипта на основе среды вы можете ссылаться на соответствующий файл свойств в скрипте.

Скажем, в A и B в HomePage есть текстовое поле с различными локаторами.

Таким образом, в файле свойств А мы можем отметить элемент как HomePage_Name_TextBox = id_NameInA «id_NameInA» это значение локатор и «HomePage_Name_TextBox» является строка, которую вы собираетесь использовать для обозначения этого конкретного элемента.

Как мудрый в файл свойство А можно упомянуть тот же элемент, HomePage_Name_TextBox = id_NameInB «id_NameInB» это значение локатора и «HomePage_Name_TextBox» является строкой, которую вы собираетесь использовать для обозначения этого конкретного элемента.

Вы можете заметить, что оба элемента имеют одно и то же имя (HomePage_Name_TextBox), а значения локаторов различны.

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

public class HomePage { 

    Map<String, String> elementsMap = new HashMap<String, String>(); 

    //Option 1 
    public HomePage(Map<String, String> elementMapObj) { 
     elementsMap = elementMapObj; 
    } 

    //Option 2 
    public HomePage() { 
     Properties    prop  = new Properties(); 
     FileReader    reader; 
     HashMap<String, String> propertyMap = new HashMap<String, String>(); 

     try { 
      reader = new FileReader(new File("CommonConfig.properties")); 
      prop.load(reader); 
      for (String key : prop.stringPropertyNames()) 
      { 
       String value  = prop.getProperty(key); 
       propertyMap.put(key, value); 
      } 
     } catch (Exception e) { 
      //System.out.println(e.toString()); 
     } 

     try { 
      reader = new FileReader(new File(propertyMap.get("ElementPropFilePath"))); 
      prop.load(reader); 
      for (String key : prop.stringPropertyNames()) 
      { 
       String value  = prop.getProperty(key); 
       elementsMap.put(key, value); 
      } 
     } catch (Exception e) { 
      //System.out.println(e.toString()); 
     } 

    } 
} 
  1. Вы можете объявить параметризованный конструктор и передать объект на карту, где вы все элементы чтения перед инициализацией объекта HomePage (в главном классе вы можете прочитать файл свойств соответствующего элемента и передать карту содержащий все элементы в конструкторе домашней страницы)
  2. ИЛИ вы можете прочитать общий файл свойств в самом конструкторе HomePage, где вы можете указать путь файла свойств Elements. ex: CommonConfig.properties Этот файл может содержать все детали конфигурации, такие как в среде, в которой запущены скрипты, и общие пути к файлам для чтения (например, где путь к файлу элемента) и этот файл будут прочитаны внутри конструктора конфигурационный файл будет выглядеть следующим образом
    ElementPropFilePath = Ресурсы/Elements_A.properties

Если вы хотите запускать скрипты в A, вы можете изменить «ElementPropFilePath» в общем файле свойств в «Ресурсы/Elements_A.properties "перед запуском. Если вы хотите запускать скрипты в B, вы можете изменить «ElementPropFilePath» в общем файле свойств на «Resources/Elements_B.properties» перед запуском (это местоположение файла на машине).

Просто скажите, если вы сохраняете файлы свойств, содержащие все элементы для каждой среды, и предоставляете эти данные о свойствах и заполняете элементMap, который у вас есть внутри каждого класса страниц, тогда вы сможете ссылаться на этот элемент с общим строка, которую вы использовали для обеих окружений (в данном примере это HomePage_Name_TextBox)

 Смежные вопросы

  • Нет связанных вопросов^_^