Page Object Model Best Practices в Selenium - PullRequest
23 голосов
/ 03 ноября 2011

Когда вы моделируете объекты вашей страницы, как бы вы справились со страницей, на которой есть форма и около 50 полей ввода? Какова лучшая практика здесь?

Не могли бы вы создать объект страницы и написать отдельную функцию для каждого действия ввода? или вы написали бы одну функцию, параметры которой передаются ей и вводятся в текст?

, например

public void enterFirstName(String firstName) {
    driver.type("firstNameField", firstName);
}

public void enterSecondName(String secondName) {
    driver.type("secondNameField", secondName);
}

или

public void fillInForm(String inputFieldName, String text) {
    driver.type(inputFieldName, text);
}

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

Этот пост также весьма интересен для структурирования тестов селена в объектах Page. Рекомендации по функциональному автоматизированному тестированию с Selenium WebDriver

Ответы [ 6 ]

10 голосов
/ 03 ноября 2011

Идея, лежащая в основе объектной модели страницы, заключается в том, что она абстрагирует реализацию от вызывающей стороны. В первом механизме вы успешно делаете это, потому что вызывающей стороне не нужно знать, изменяется ли имя поля ввода html с «firstName» на «user_first_name», тогда как во второй реализации любые изменения в реальной странице должны быть поступил ко всем вызывающим объектам вашей страницы объекта.

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

9 голосов
/ 03 ноября 2011

Мне всегда нравится разбивать вещи на группы связанной информации.Например, если у меня есть пользовательский класс, я могу разбить его на несколько более мелких классов: LoginCredentials, ProfileInfo, Settings и т. Д., Но у меня все равно будет класс пользователя верхнего уровня, содержащий эти подклассы.

Одна вещь, которую я бы порекомендовал, это передать объект одной функции FillForm, а не всем этим отдельным функциям.Есть несколько больших преимуществ использования этого подхода.Во-первых, у вас могут быть «общие» предварительно сконфигурированные объекты, которые вы используете для многих тестовых случаев.Например:

public class FormInfo
{
   string Domain;
   string Name;
   string Category;
   // etc...

  public FormInfo(string domain, string name, string category)
  {
     Domain = domain;
     Name = name;
     Category = category;
     // etc...
  }
}


// Somewhere in your initialization code
public static FormInfo Info1 = new FormInfo("myDomain1", "myName1", "myCategory1");
public static FormInfo Info2 = new FormInfo("myDomain2", "myName2", "myCategory2");

You can still update one of your common merchants if you need to do something one-off:

// In your test case:
Info1.Category = "blah";
FormPage.FillForm(Info1);

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

Info1.Domain = null; //This should make the FillForm function skip doing anything with this field.
FormPage.FillForm(Info1);
FormPage.DomainTextBox.Text = "field validation string";

Другим важным преимуществом этого подхода является то, что если страница когда-либо обновляется для добавления, удаления или изменения полей, вам нужно будет только обновить объект FormInfo и функцию FillForm, а также не нужно изменять конкретные тестовые случаи, которые вызывают FillFormфункция - при условии, что они используют один из ваших общих объектов FormInfo.Другая возможность получить большее покрытие - это настроить один из ваших общих объектов FormInfo для генерации случайных строк для каждого из полей, которые соответствуют минимальной / максимальной длине и циклу между всеми различными разрешенными символами.Это позволяет вам провести дополнительное тестирование из того же набора тестов, хотя это также может добавить некоторый шум, если вы начнете получать результаты сбоев только из определенных строк, поэтому будьте осторожны.

1 голос
/ 24 октября 2016

Я отвечаю на старый вопрос в интересах читателей.

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

Объекты страницы - это хорошо известный шаблон проектирования, широко принятый инженерами по автоматизации для создания отдельного файла класса для каждой страницы приложения, чтобы сгруппировать все элементы как свойства и их поведение / бизнес-функции как методы класса.Но у него мало проблем с созданием класса для страницы, особенно когда на странице больше / разных наборов элементов / сложных элементов, таких как сетка / виджет календаря / таблица HTML и т. Д.

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

Проверьте изображение здесь для идеи.

enter image description here

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

Проверьте здесь для получения дополнительной информации.

1 голос
/ 04 ноября 2011

В дополнение к вашим enterWhatever() методам я обычно также создаю метод createWhatever(field1, field2, ...), который я могу использовать в качестве быстрого пути для создания того, что строит форма, для использования, когда цель real тест это нечто другое.Таким образом, если мне нужно создать клиента для проверки отправки билета, тест переходит на страницу CreateACustomer и просто вызывает createCustomer(firstName, lastName, emailAddress, ...), а затем переходит к более детальной задаче создания билета с использованием этого клиента.

0 голосов
/ 29 мая 2014

Пожалуйста, ознакомьтесь с файлом readme, https://github.com/yujunliang/seleniumcapsules

0 голосов
/ 03 ноября 2011

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

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

Что сводится к тому, что все, что мне нужно сделать, чтобы проверить страницу, это:

for (int i = 0; i < inputs.Count(); i++)
{
  //This captures the error message string created in the input validation method
  //nextButton is the IWebElement of the button to click to submit the form for validation
  //ErrorMessageID is the ID of the Validation Summary display box (i.e. ErrorMessageID = "FormSummary" <asp:ValidationSummary ID="FormSummary" runat="server" CssClass="errorMessage" />

  string InputValidationText = utilities.InputValidation(driver, inputs, i, nextButton, ErrorMessageID)
  if(InputValidationText != string.Empty)
  {
    //LogError
  }
}
...