Абстракция
Давайте разберем, все очень просто. Абстракция похожа на использование пульта дистанционного управления телевизором. Вы нажимаете кнопки, чтобы переключить канал или отрегулировать громкость, но вам не нужно знать, как пульт посылает сигналы на телевизор. Вы просто видите результат.
Теперь посмотрим, как это работает в Selenium.
Представьте, что у вас есть большая книга (ваше веб-приложение), и вы хотите найти определенные слова (элементы на странице). Вместо того чтобы каждый раз перелистывать всю книгу, вы используете закладку (локатор), чтобы перейти на страницу.
В паттерне проектирования Page Object Model:
- Мы создаем специальный класс (Page Class), в котором записываем все закладки (локаторы, такие как id, name, xpath и т. д.) и методы (действия, которые вы можете выполнять на странице).
- Когда мы пишем тесты, мы используем эти закладки для поиска слов, но нам не нужно знать, как эти закладки создавались или как они работают.
Проще говоря, мы скрываем сложные вещи (как работают закладки) и просто используем простые вещи (сами закладки) в наших тестах. Это и есть абстракция!
Интерфейс
Вы знаете оператор в Selenium: `WebDriver driver = new FirefoxDriver();`
Вот почему мы так пишем: WebDriver — это интерфейс. Воспринимайте интерфейс, как контракт. В контракте говорится: «Любой класс, подписавший этот контракт, должен делать определенные вещи». В данном случае WebDriver — это контракт.
FirefoxDriver — это класс: это как конкретный сотрудник, который соглашается следовать контракту. FirefoxDriver — это класс, который знает, как управлять браузером Firefox.
Создание ссылочной переменной: Когда мы пишем `WebDriver driver`, мы говорим: «Эй, мне нужен сотрудник, который может следовать контракту WebDriver». `driver` — это просто обозначение имени этого сотрудника.
Инициализация браузера: Когда мы пишем `new FirefoxDriver()`, мы нанимаем конкретного сотрудника, который знает, как управлять браузером Firefox.
Таким образом, `WebDriver driver = new FirefoxDriver();` означает: — Мы просим сотрудника (`driver`), который может следовать контракту WebDriver.
— Мы нанимаем конкретного сотрудника (`new FirefoxDriver()`), который знает, как управлять браузером Firefox.
В Java интерфейс (WebDriver) — это как чертеж. В нем могут быть методы и переменные, но методы — это просто обещания (абстрактные), которые должны быть выполнены любым классом, подписавшим контракт. Это позволяет нам достичь стопроцентной абстракции и множественного наследования, то есть у нас могут быть разные сотрудники (например, ChromeDriver, FirefoxDriver), выполняющие один и тот же контракт (WebDriver).
Наследование
Наследование в Java — это как семейная традиция. Один класс (дочерний) получает все важные вещи (свойства и функциональные возможности) от другого класса (родительского).
Вот как это работает в фреймворке:
Базовый класс: Считайте, что это родительский класс. Он содержит все важные вещи, такие как инициализация WebDriver, настройка ожиданий, чтение файлов свойств, работа с файлами Excel и т. д.
Другие классы (тесты, классы-утилиты): Это дочерние классы. Они получают от родительского (базового) класса все крутые возможности без необходимости писать их заново.
Поэтому, когда мы говорим, что расширяем базовый класс в других классах, это означает, что дочерние классы (например, Tests и Utility Class) наследуют все свойства и функциональные возможности от родительского (базового) класса.
Проще говоря, наследование позволяет нам повторно использовать уже единожды написанный код. Мы пишем важные вещи один раз в базовом классе, а затем просто расширяем его в других классах, чтобы использовать эти вещи. Таким образом, нам не придется снова писать один и тот же код.
Полиморфизм
Полиморфизм — это как швейцарский армейский нож. Он позволяет выполнять задачу несколькими способами, используя один и тот же инструмент.
Полиморфизм — это комбинация перегрузки и переопределения. Посмотрим, что это означает:
- Перегрузка методов
Перегрузка методов — это как несколько лезвий в вашем швейцарском армейском ноже. Каждое лезвие (метод) имеет одно и то же имя, но делает разные вещи в зависимости от того, что вам сейчас нужно.
— Пример: Неявное ожидание в Selenium. Вы можете задать время ожидания в секундах, минутах и т. д. Название метода одинаковое, но параметры (единицы измерения времени) разные.
— Еще один пример: Класс `Action` в TestNG. Вы можете выполнять различные действия, используя методы с одинаковым именем, но разными параметрами.
— Еще один пример: Класс `Assert` в TestNG. Вы можете проверять различные условия, используя методы с одним и тем же именем, но разными параметрами.
Таким образом, перегрузка методов означает наличие нескольких методов с одним и тем же именем, но разными параметрами.
- Переопределение методов
Переопределение методов — это как настройка лезвия в вашем швейцарском армейском ноже. Вы берете уже существующее лезвие (метод) и изменяете его вид.
— Пример: В Selenium у разных драйверов (например, ChromeDriver, FirefoxDriver) есть методы `get` и `navigate`. Эти методы делают одно и то же (открывают URL), но реализованы по-разному для каждого драйвера.
Таким образом, переопределение метода означает объявление в дочернем классе метода, который уже существует в родительском классе, но изменение его реализации.
Проще говоря, полиморфизм позволяет нам использовать одно и то же имя метода для выполнения различных действий (перегрузка) или для изменения существующих методов (переопределение).
Инкапсуляция
Инкапсуляция — это как упаковка всех инструментов в ящик для инструментов. Все аккуратно сложено, чтобы вы могли легко найти и использовать тот, который вам нужен.
В фреймворке автоматизации все классы являются примерами инкапсуляции. Вот как это работает:
Классы POM: Считайте их своими ящиками. Внутри них находятся инструменты (данные), которые нужны вам для тестов. Мы объявляем эти инструменты с помощью @FindBy, чтобы найти элементы на веб-странице. Мы инициализируем эти инструменты с помощью конструктора, чтобы они были готовы к использованию в методах.
Итак, инкапсуляция — это механизм связывания кода и данных (переменных) в единое целое (класс).
Проще говоря, инкапсуляция помогает нам все упорядочить. Мы помещаем весь связанный код и данные в один класс, что упрощает управление и использование. Эта упрощенная диаграмма показывает, как все эти концепции работают во фреймворке автоматизации:
В чем заключается Абстракция: WebDriver является интерфейсом (контрактом), и FirefoxDriver является классом, имплементирующим этот интерфейс. Подробности того, как работают get() и FindElement() — скрыты.
В чем заключается Полиморфизм: И ChromeDriver, и FirefoxDriver имплементируют интерфейс WebDriver, но предоставляют собственные версии методов get и navigate. Это переопределение метода (полиморфизм).
В чем заключается Наследование: TestClass наследуется из BaseClass, это значит что он получает все методы и свойства BaseClass без переписывания их заново.
В чем заключается Инкапсуляция: Класс LoginPage инкапсулирует элементы (юзернейм, пароль, LoginButton) и метод логина. Элементы инициализируются конструктором и используются в методах класса.