Ответ
Полиморфизм в Java — это возможность объекта принимать множество форм. В контексте написания автотестов он активно используется для создания гибких и расширяемых фреймворков. Основные виды:
1. Полиморфизм времени выполнения (Runtime / Переопределение методов)
Самый частый случай. Дочерний класс переопределяет метод родительского, и JVM во время выполнения определяет, какую реализацию вызвать.
Пример в тестовом фреймворке (Page Object Model):
// Базовый класс для всех страниц
abstract class BasePage {
protected WebDriver driver;
public BasePage(WebDriver driver) { this.driver = driver; }
// Абстрактный метод, который должен быть реализован в каждой странице
public abstract boolean isPageLoaded();
// Общий метод с реализацией по умолчанию
public void takeScreenshot(String name) {
System.out.println("Taking screenshot: " + name);
// ... логика скриншота
}
}
// Конкретная страница
class LoginPage extends BasePage {
private By usernameField = By.id("user");
public LoginPage(WebDriver driver) { super(driver); }
// ПОЛИМОРФИЗМ: Переопределяем метод проверки загрузки
@Override
public boolean isPageLoaded() {
return driver.findElement(usernameField).isDisplayed();
}
// Свой специфичный метод
public void login(String user, String pass) { /* ... */ }
}
// В тесте
BasePage page = new LoginPage(driver); // Ссылка типа BasePage, объект LoginPage
page.isPageLoaded(); // Вызовется реализация из LoginPage
page.takeScreenshot("login"); // Вызовется унаследованная реализация из BasePage
2. Полиморфизм времени компиляции (Compile-time / Перегрузка методов)
Несколько методов с одним именем, но разными параметрами.
class TestDataFactory {
// Разные способы создания пользователя
User createUser(String email) { /* ... */ }
User createUser(String email, String role) { /* ... */ } // Перегрузка
User createUser(UserTemplate template) { /* ... */ } // Перегрузка
}
3. Полиморфизм через интерфейсы
Позволяет достичь максимальной гибкости и соблюсти принцип Dependency Inversion (SOLID).
Пример (Стратегия для драйверов):
interface WebDriverFactory {
WebDriver createDriver();
}
class ChromeDriverFactory implements WebDriverFactory {
@Override
public WebDriver createDriver() { return new ChromeDriver(); }
}
class RemoteDriverFactory implements WebDriverFactory {
@Override
public WebDriver createDriver() {
return new RemoteWebDriver(new URL("http://grid:4444"), new ChromeOptions());
}
}
// В базовом тесте
public class BaseTest {
protected WebDriver driver;
@BeforeEach
void setUp() {
// Полиморфизм: система не знает, какой именно фабрикой мы пользуемся
WebDriverFactory factory = Config.getDriverFactory(); // Возвращает ChromeDriverFactory или RemoteDriverFactory
driver = factory.createDriver(); // Создаст нужный драйвер
}
}
Практическая польза для QA-инженера:
- Снижение дублирования кода: Общая логика (скриншоты, логирование) выносится в
BasePage/BaseTest. - Упрощение поддержки: Добавление новой страницы (
CheckoutPage) не требует изменения существующего кода тестов, работающего сBasePage. - Гибкость конфигурации: Легко подменить реализацию (например, переключиться с локального Chrome на Selenium Grid) через смену фабрики, не трогая сами тесты.
- Чистая архитектура фреймворка: Полиморфизм — основа многих паттернов (Page Object, Factory, Strategy), используемых в профессиональных тестовых фреймворках.