# Наиболее распространенные шаблоны проектирования в тестировании

### 🔹 **1. Page Object (PO)**

👉 Один из самых популярных шаблонов в тестировании UI.

* Каждая веб-страница (или её часть) описывается в виде **класса**.
* Все элементы и действия инкапсулируются внутри этого класса.

✅ Преимущества:

* Убирает дублирование кода.
* Делает тесты более читаемыми.
* Легко поддерживать при изменении UI.

Пример:

```python
class LoginPage:
    def __init__(self, driver):
        self.driver = driver

    def enter_username(self, username):
        self.driver.find_element("id", "username").send_keys(username)

    def enter_password(self, password):
        self.driver.find_element("id", "password").send_keys(password)

    def submit(self):
        self.driver.find_element("id", "login").click()
```

***

### 🔹 **2. Page Factory**

👉 Расширение Page Object.

* Использует аннотации/декораторы для инициализации элементов.
* Например, в **Java + Selenium** часто через `@FindBy`.
* В Python можно реализовать через property/декораторы.

***

### 🔹 **3. Singleton**

👉 Когда нужно, чтобы в системе существовал только один объект.\
Применяется в тестировании:

* Для **WebDriver** (например, чтобы не создавать несколько браузеров).
* Для **подключений к БД**.

***

### 🔹 **4. Factory Method**

👉 Позволяет создавать разные объекты, не указывая конкретный класс.\
В тестировании используется для:

* Создания **Page Objects**.
* Генерации **тестовых данных**.

***

### 🔹 **5. Builder**

👉 Позволяет пошагово собирать сложные объекты.\
В тестировании часто применяют:

* Для генерации сложных **тестовых данных** (например, JSON-запросов).

Пример:

```python
class UserBuilder:
    def __init__(self):
        self.user = {"name": "", "age": 0, "email": ""}

    def with_name(self, name):
        self.user["name"] = name
        return self

    def with_age(self, age):
        self.user["age"] = age
        return self

    def with_email(self, email):
        self.user["email"] = email
        return self

    def build(self):
        return self.user

# Использование
user = UserBuilder().with_name("Alice").with_age(30).with_email("a@a.com").build()
```

***

### 🔹 **6. Strategy**

👉 Определяет семейство алгоритмов и делает их взаимозаменяемыми.\
В тестировании часто используется:

* Для выбора разных способов **логина** (через UI, API, токен).
* Для разных **стратегий ожидания**.

***

### 🔹 **7. Decorator**

👉 Позволяет динамически добавлять функционал.\
В тестировании используется:

* Для **логирования** шагов теста.
* Для **ретраев** (повторного запуска теста при фейле).

***

### 🔹 **8. Observer**

👉 Один объект следит за событиями в другом.\
В тестировании может применяться:

* Для **логирования** (подписка на событие "тест упал").
* Для интеграции с **репортинг-системами** (Allure, TestRail).

***

### 🔹 **9. Data Driven Testing (шаблон проектирования в тестах)**

👉 Тесты отделены от данных.

* Тесты берут входные данные из CSV/Excel/JSON/БД.
* Позволяет легко добавлять новые сценарии без изменения кода.

***

### 🔹 **🔟 Keyword Driven Testing**

👉 Более высокий уровень абстракции.

* Тесты описываются как последовательность ключевых слов (например, "Login", "Search", "Logout").
* Используется в крупных проектах (Robot Framework).

***

## 📌 Шаблоны проектирования в тестировании

| 🏷 Шаблон          | 📖 Идея                                           | 🤔 Где используется в тестах         | 💻 Пример                                               |
| ------------------ | ------------------------------------------------- | ------------------------------------ | ------------------------------------------------------- |
| **Page Object**    | Каждая страница/экран → класс                     | UI тесты (Selenium, Appium)          | `LoginPage().enter_username("user")`                    |
| **Page Factory**   | Автоматическая инициализация элементов            | Java Selenium, Python property       | `@FindBy(id="username")`                                |
| **Singleton**      | Один объект на всё приложение                     | WebDriver, DB подключение            | `driver = Driver.get_instance()`                        |
| **Factory Method** | Создание объектов без указания конкретного класса | Создание Page Objects, API клиентов  | `PageFactory.create("Login")`                           |
| **Builder**        | Пошаговая сборка сложного объекта                 | Генерация тестовых данных, JSON тел  | `UserBuilder().with_name("Alice").with_age(30).build()` |
| **Strategy**       | Разные алгоритмы взаимозаменяемы                  | Разные способы логина, ожидания      | `login_strategy.execute()`                              |
| **Decorator**      | Динамическое добавление функционала               | Логирование шагов, ретраи тестов     | `@log_step`                                             |
| **Observer**       | Подписка на события                               | Интеграция с Allure/TestRail         | "onTestFail → отправить в Slack"                        |
| **Data Driven**    | Данные отдельно от теста                          | CSV/Excel/JSON для параметризации    | `@pytest.mark.parametrize`                              |
| **Keyword Driven** | Тест = последовательность ключевых слов           | Robot Framework, высокоуровневые DSL | `Login → Search → Logout`                               |

***

⚡ Быстрая визуализация:

* **UI тесты** → Page Object, Page Factory, Singleton.
* **API тесты** → Builder (данные), Factory, Strategy.
* **Фреймворки и репорты** → Observer, Decorator.
* **Массовые сценарии** → Data Driven, Keyword Driven.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kaze.gitbook.io/qa-theory/teoriya-avtomatizirovannogo-testirovaniya/obshie-voprosy/naibolee-rasprostranennye-shablony-proektirovaniya-v-testirovanii.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
