Ответ
В автоматизации тестирования паттерны проектирования решают проблемы поддержки, читаемости и масштабируемости тестового кода.
1. Page Object Model (POM) — фундаментальный паттерн Каждая страница/компонент UI представляется классом, который инкапсулирует:
- Локаторы элементов
- Методы взаимодействия
- Проверки состояния
public class LoginPage
{
private readonly IWebDriver _driver;
private readonly By _usernameField = By.Id("username");
private readonly By _passwordField = By.Id("password");
private readonly By _submitButton = By.CssSelector("button[type='submit']");
public LoginPage(IWebDriver driver) => _driver = driver;
public void EnterCredentials(string username, string password)
{
_driver.FindElement(_usernameField).SendKeys(username);
_driver.FindElement(_passwordField).SendKeys(password);
}
public DashboardPage Submit()
{
_driver.FindElement(_submitButton).Click();
return new DashboardPage(_driver); // Возвращает следующую страницу
}
}
2. Page Factory (упрощённая реализация POM)
Использование атрибутов [FindsBy] для автоматической инициализации элементов (хотя в Selenium 4 рекомендуется прямой подход).
3. Loadable Component Pattern Добавление явных ожиданий загрузки страницы/компонента.
public class DashboardPage : LoadableComponent<DashboardPage>
{
protected override void ExecuteLoad() => Driver.Navigate().GoToUrl("/dashboard");
protected override bool EvaluateLoadedStatus() => Driver.Title.Contains("Dashboard");
}
4. Singleton для WebDriver Гарантирует единственный экземпляр драйвера на весь тестовый прогон.
public sealed class WebDriverManager
{
private static IWebDriver _instance;
private static readonly object _lock = new object();
public static IWebDriver Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
_instance ??= new ChromeDriver();
}
}
return _instance;
}
}
}
5. Factory Method для создания драйверов
public interface IWebDriverFactory
{
IWebDriver CreateDriver();
}
public class ChromeDriverFactory : IWebDriverFactory
{
public IWebDriver CreateDriver() => new ChromeDriver();
}
6. Builder для тестовых данных
public class UserBuilder
{
private string _name = "Default";
private string _email = "default@test.com";
public UserBuilder WithName(string name) { _name = name; return this; }
public UserBuilder WithEmail(string email) { _email = email; return this; }
public User Build() => new User(_name, _email);
}
// Использование
var user = new UserBuilder().WithName("John").WithEmail("john@example.com").Build();
7. Strategy для выбора стратегии тестирования Например, разные стратегии аутентификации (OAuth, JWT, Basic Auth).
8. Decorator для добавления логирования/ретров
public class LoggingWebDriverDecorator : IWebDriver
{
private readonly IWebDriver _decoratedDriver;
public LoggingWebDriverDecorator(IWebDriver driver) => _decoratedDriver = driver;
public void FindElement(By by)
{
Console.WriteLine($"Finding element: {by}");
return _decoratedDriver.FindElement(by);
}
}
9. Composite для группировки тестовых шагов
10. Data-Driven Testing через Provider Pattern Отделение тестовых данных от тестовой логики.
Ключевой принцип: Паттерны должны упрощать код, а не усложнять его. Начинайте с POM и добавляйте другие паттерны только при реальной необходимости.