Добрый день!
В третьей части этой серии статей мы добавили нативную поддержку тестирования API в нашу платформу автоматизации тестирования. В этой статье мы организуем нашу тестовую среду для размещения объектной модели страницы, также известной как POM, для веб-элементов пользовательского интерфейса.
Allons-y!
Что такое объектная модель страницы?
Объектная модель страницы (POM) – это широко используемый в автоматизации тестирования шаблон проектирования, который создает репозиторий объектов для элементов веб-интерфейса. Преимущество модели в том, что она уменьшает дублирование кода и улучшает сопровождение тестов.
Согласно этой модели, для каждой веб-страницы в приложении должен быть соответствующий класс страницы. Этот класс Page идентифицирует веб-элементы этой веб-страницы, а также содержит методы страницы, которые выполняют операции с этими веб-элементами. Имя этим методам должно быть дано в соответствии с выполняемой ими задачей, т. е. если загрузчик ожидает появления платежного шлюза, имя метода POM может быть 'waitForPaymentScreenDisplay()'.[1]
Преимущества POM
- Шаблон Page Object Pattern говорит, что операции и потоки в пользовательском интерфейсе должны быть отделены от проверки. Эта концепция делает наш код чище и проще для понимания.
- Вторым преимуществом является то, что репозиторий объектов не зависит от тестовых случаев, поэтому мы можем использовать один и тот же репозиторий объектов для разных целей с помощью разных инструментов. Например, мы можем интегрировать POM с TestNG/JUnit для функционального тестирования и одновременно с JBehave/Cucumber для приемочного тестирования.
- Код становится меньше, оптимизирован и прост в обслуживании благодаря многократно используемым методам страницы в классах POM.
- Методы получают более реалистичные имена, которые можно легко сопоставить с операцией, происходящей в пользовательском интерфейсе. т. е. если после нажатия на кнопку мы попадаем на домашнюю страницу, имя метода будет выглядеть как ‘gotoHomePage()’.
Интеграция объектной модели страницы
Чтобы добавить объекты Page в нашу существующую структуру, нам не нужны никакие дополнительные функции Cypress или внешние библиотеки JS. Все, что нам нужно сделать, это немного изменить структуру нашего проекта, чтобы включить классы страниц и добавить соответствующие элементы и действия в так называемые "Страницы".
Давайте начнем немного расширять наш тестовый пример пользовательского интерфейса, так как он проверяет только заголовок, поэтому веб-элементы не используются.
Добавление новых тестовых шагов для ввода поискового запроса и последующей проверки первого результата поиска на Google.com.
//Updated Test Case
@UI Feature: Navigating to Google.com and verifying title and match result keyword @smoke @test Scenario: Perform Search Given I open the Google web url Then I verify title of web page as 'Google' When I provide search query as "Pokemon" Then Verify first search result to match "Pokemon" keyword
Теперь добавьте новую папку в /integration с именем pages:
Теперь, когда мы будем вводить ключевое слово для поиска в поле ввода на главной странице Google, а затем проверять результат на странице результатов поиска. Таким образом, мы можем сказать, что у нас есть 2 страницы, и мы должны хранить элементы и действия для этих 2 страниц.
Теперь мы создадим 2 папки для страниц HomePage и ResultPage соответственно.
Как мне нравится группировать элементы и действия на странице; Я создаю 2 отдельных файла JS, по одному для элементов и действий Cypress. Так, например, в папке HomePage elements.js хранит веб-элементы, а HomePage.js хранит действия Cypress.
Элементы домашней страницы — это простой файл module.exports, который содержит объект HOMEPAGE для хранения своих веб-элементов:
//elements.js for HomePage
module.exports = {
HOMEPAGE:{
SEARCH_TXTBOX: "input[name='q']"
}
}
Аналогично для элементов ResultPage:
//elements.js for HomePage
module.exports = {
RESULTPAGE:{
SEARCH_RESULT_FIRST: "div.rc"
}
}
На основе этих элементов мы напишем наши действия для HomePage:
//HomePage.js
var elements = require('./elements')
class HomePage {
clickSearchTxtBox() {
return cy.get(elements.HOMEPAGE.SEARCH_TXTBOX).click();
}
typeInSearchTxtBox(value) {
return cy.get(elements.HOMEPAGE.SEARCH_TXTBOX).type(value);
}
submitSearchQuery() {
//press enter after query is provided, for submission
return cy.get(elements.HOMEPAGE.SEARCH_TXTBOX).type('{enter}');
}
}
export default HomePage;
и действия ResultPage:
//ResultPage.js
var elements = require('./elements')
class ResultPage {
verifyFirstResult(search_keyword) {
//matches partial text of result string
return cy.get(elements.RESULTPAGE.SEARCH_RESULT_FIRST).first().text().then(value => {
cy.log("Text is :", value);
expect(value).to.include(search_keyword);
});
}
}
export default ResultPage;
Одна важная вещь: функция cypress text() отсутствует по умолчанию, мы должны написать пользовательскую команду в файле /support/command.js следующим образом:
Cypress.Commands.add("text", { prevSubject: true }, (subject, options) =› { return subject.text();
});
Теперь, когда у нас есть наша объектная модель страницы, мы можем добавить ее к нашим шагам BDD.
Шаги BDD с объектной моделью страницы:
Чтобы использовать Page Classed в нашем проекте, нам нужно сначала импортировать его в файл Step-Definition commonStep.js, используя оператор импорта.
//
Page imports into commonStep.js fileimport HomePage from '../../../pages/HomePage/HomePage'; import ResultPage from '../../../pages/ResultPage/ResultPage'; const homePage = new HomePage(); const resultPage = new ResultPage(); ...
и шаги BDD будут выглядеть так:
//
BDD Steps in commonSteps.jsGiven('I open the Google web url', () => { cy.visit('https://www.google.com'); }); Then( 'I verify title of web page as {string}', (title) => { cy.title().should('include', title); } ); When( 'I provide search query as {string}', (query) => { homePage.clickSearchTxtBox(); homePage.typeInSearchTxtBox(query); homePage.submitSearchQuery(); } ); Then( 'Verify first search result to match {string} keyword', (search_keyword) => { let result = resultPage.verifyFirstResult(search_keyword); } );
Это все. Все, что нам нужно сделать, это запустить этот тест, используя следующую команду:
npx cypress run --env TAGS="@UI"
или через интерфейс Cypress:
npx cypress open
— env TAGS="@UI" обеспечивает запуск только теста пользовательского интерфейса, пропуская выполнение теста API
Результат теста:
ИЛИ, используя интерфейс Cypress:
Вот и все, мы интегрировали POM в нашу структуру.
Если вы хотите увидеть все видео тестового прогона; вы можете просто перейти в следующую папку: cypress\videos\features\UI, и там вы найдете Test1.js.mp4, в котором будет записано полное выполнение тестового запуска.
Увидимся в следующий раз, когда мы увидим добавление некоторых других интересных вещей в наши фреймворки, таких как отчеты, поддержка нескольких сред и т. д. Так что следите за обновлениями. Часть 5 теперь доступна.
До свидания!
Репозиторий GitHub: https://github.com/far11ven/Cypress-TestFramework/tree/develop/Part 04
Первоначально опубликовано на https://kushalbhalaik.xyz/blog 4 октября 2020 г.