Подтвердить что ты не робот

Объектная модель страницы: почему бы не включить утверждения в методы страниц?

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

С http://code.google.com/p/selenium/wiki/PageObjects:

Код, представленный выше, показывает важный момент: тесты, а не PageObjects, должны нести ответственность за утверждение о состояние страницы.... Конечно, как и в каждом руководстве есть исключения...

С http://seleniumhq.org/docs/06_test_design_considerations.html#chapter06-reference:

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

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

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

Например, давайте представим, что когда вы входите в свой AUT, появляется какой-то текст с надписью "зарегистрирован как пользователь". Целесообразно иметь один тест для конкретной проверки, но почему вы не хотите проверять его каждый раз, когда вызывается логин? Этот артефакт не имеет прямого отношения к тому, "правильно ли загружена" страница или нет, и он не имеет отношения к "тому, что тестируется" в целом, поэтому в соответствии с указаниями POM, приведенными выше, он явно НЕ ДОЛЖЕН быть в методе страницы.... но мне кажется, что это ДОЛЖНО быть, чтобы максимизировать мощность автоматизации, проверяя важные артефакты как можно чаще, с минимальным количеством обдуманных решений. Внедрение кода подтверждения в методы страницы увеличивает мощность автоматизации, позволяя вам получить много проверок "бесплатно", не беспокоясь об этом в своих тестах, и такая частая проверка в разных контекстах часто приводит к проблемам, которые вы НЕ найдете если проверка была ограничена, скажем, одним тестом для этого артефакта.

Другими словами, я склонен проводить различие между верификацией для конкретного теста и "общей" верификацией, и я считаю, что это вполне уместно/желательно для того, чтобы последняя широко использовалась в методах страницы. Это способствует более тонким тестам и более толстым объектам страниц, что, как правило, повышает удобство сопровождения тестов за счет повторного использования большего количества кода - несмотря на противоречивые утверждения в этих рекомендациях. Я упускаю суть? Каково реальное обоснование НЕ желая проверки в методах страницы? Является ли описанная мною ситуация фактически одним из "исключений", описанных в этих руководящих принципах, и поэтому на самом деле НЕ противоречит POM? Заранее спасибо за ваши мысли. -jn-

4b9b3361

Ответ 1

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

  • Довольно сложно прочитать тест, который просто вызывает методы verify, где утверждения скрыты в других местах объектов страницы. Там, где это возможно, должно быть очевидно, что утверждает тест; это лучше всего достигается, когда утверждения находятся непосредственно в тесте. Скрывая утверждения где-то вне теста, цель теста не так ясна.

  • Утверждения в тестах браузера могут быть дорогими - они могут действительно замедлить ваши тесты. Когда у вас есть сотни или тысячи тестов, минуты/часы могут быть добавлены к вашему времени выполнения теста; это Плохая Вещь. Если вы переместите утверждения только на те тесты, которые заботятся об этих конкретных утверждениях, вы обнаружите, что у вас будут гораздо более быстрые тесты, и вы по-прежнему поймаете соответствующие дефекты. Вопрос включал следующее:

    Ввод кода проверки в методы страницы умножает мощь автоматизации, позволяя вам получить большую проверку "бесплатно"

    Ну, "Свобода не свободна":) То, что вы на самом деле умножаете, - это время выполнения теста.

  • Наличие утверждений повсюду нарушает другое хорошее руководство; "Одно утверждение на тест" (http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html). Я не придерживаюсь религиозно, но стараюсь следовать принципу. По возможности, тест должен быть заинтересован только в одной вещи.

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

    Например, представьте себе, что, когда вы входите в свой AUT, появляется какой-то текст, который говорит "вошел в систему как USER". Уместно, чтобы один тест подтвердил это конкретно, но почему бы вам не проверить его каждый раз, когда вызывается логин?

    Если у вас есть утверждение в классе объекта страницы и ожидаемые изменения текста, все тесты, которые войдут в систему, не удастся. Если вместо этого утверждение находится в тесте, то только один тест потерпит неудачу - тот, который специально проверяет правильное сообщение, - оставив все остальные тесты продолжать работать, чтобы найти другие ошибки. Вам не нужно 5000 тестов, чтобы сообщить вам, что сообщение для входа неверно; 1 тест будет делать;)

  • Наличие класса делает нечто большее, чем одно, нарушает "S" в SOLID, то есть: Принцип единой ответственности '(SRP). Класс должен нести ответственность за одно и только одно. В этом случае класс страницы-объекта должен отвечать за моделирование страницы (или ее раздела) и ничего более. Если он делает больше, чем это (например: включая утверждения), вы нарушаете SRP.

Ответ 2

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

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

Ответ 3

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

Ключ находится в утверждении "Конечно, как и в каждом руководстве есть исключения..."

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

page = ProfilePage.open
try 
  page.ChangePassword(old, new)
catch notLoggedIn
  page.Login(user, pass)

assert page.contains "your password has been updated"

В этом ограниченном примере вам нужно будет снова проверить (и снова), чтобы он не был лучшим способом, но вы поняли эту идею. Вы также можете просто проверить состояние (дважды)

if page.hasLoginDialog
  page.Login

if page.hasLoginDialog //(again!)
  assert.fail("can't login")

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

try 
  page = site.OpenProfilePage
catch notOnProfilePage

или имеет нужные элементы   пытаться     profilepage.changePassword(старый, новый)   catch elementNotFound

или без исключения исключений

page = site.OpenProfilePage
if ! page instanceof ProfilePage

или со сложной проверкой

assert page.looksLikeAProfilePage

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

Если вы чувствуете необходимость, вы можете вывести свои утверждения из тестового примера в тестовые вспомогательные методы.

page = site.GoToProfilePage
validate.looksLikeProfilePage(page)

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

Ответ 4

Это озадачивает меня, когда я вижу, что такое же утверждение можно использовать в нескольких методах тестирования. Например, при написании конкретного метода утверждения -

public PaymentPage verifyOrderAmount(BigDecimal orderAmount) {      
   Assertion.assertEquals(lblOrderAmount.getText(), orderAmount, "Order Amount is wrong on Payment details page"); 
   return this; 
}

Теперь я могу использовать его во всех тестах, которые мне нужны. Вместо повторения одного утверждения в нескольких тестах, связанных с несколькими сценариями. Излишне говорить, что я могу связать несколько утверждений в методе в зависимости от теста i.e -

 .verifyOrderAmount(itemPrice)
 .verifyBankAmount(discountedItemPrice)
 .verifyCouponCode(flatDiscountCode.getCouponCode()) 

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

Ответ 5

@Matt многократное использование моделей предметной области в объекте страницы может сэкономить ваше время, но это не означает, что Test Smell, тестовая логика полностью очищена от предметной модели (в зависимости от того, чего вы пытаетесь достичь).

Вернемся к исходному вопросу. Если вам действительно нужно делать утверждения в объекте страницы, почему бы не использовать selenium loadablecomponent & lt;>, где вы можете использовать метод isLoaded(), или включить свое пользовательское утверждение в класс loadablecomponent & lt;>. Это сделает ваш объект страницы свободным от утверждений. Но вы можете делать утверждения в загружаемом компоненте. Смотрите ссылку ниже...

https://github.com/SeleniumHQ/selenium/wiki/LoadableComponent

_Мечтатель

Ответ 6

Я не мог согласиться с автором.

Добавление утверждений в тестовые методы поможет вам "рано потерпеть неудачу". Под утверждениями я имею в виду проверку загрузки определенной страницы после нажатия кнопки и т.д. (Так называемые общие утверждения).

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

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