← Назад к вопросам
Какими паттернами программирования пользуешься
2.3 Middle🔥 191 комментариев
#Архитектура приложений
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Паттерны проектирования в тестировании
Page Object Model (POM)
Каждая страница/экран — отдельный класс
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 click_login(self):
self.driver.find_element("id", "login-btn").click()
class LoginTest:
def test_valid_login(self):
page = LoginPage(driver)
page.enter_username("user@test.com")
page.enter_password("password")
page.click_login()
Преимущества:
- Переиспользуемость
- Легче поддерживать
- Разделение логики и данных
Factory Pattern
Создание объектов через фабрику
class DriverFactory:
@staticmethod
def get_driver(browser):
if browser == "chrome":
return webdriver.Chrome()
elif browser == "firefox":
return webdriver.Firefox()
else:
raise ValueError(f"Unknown browser: {browser}")
driver = DriverFactory.get_driver("chrome")
Singleton Pattern
Один экземпляр для всех тестов
class DriverManager:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.driver = webdriver.Chrome()
return cls._instance
manager = DriverManager()
driver = manager.driver
Builder Pattern
Построение сложных объектов
class TestDataBuilder:
def __init__(self):
self.data = {}
def with_username(self, username):
self.data["username"] = username
return self
def with_password(self, password):
self.data["password"] = password
return self
def build(self):
return self.data
data = TestDataBuilder()\
.with_username("john")\
.with_password("pass")\
.build()
AAA (Arrange-Act-Assert)
Структура теста
def test_add_user():
# Arrange
user_data = {"name": "John", "email": "john@test.com"}
# Act
response = requests.post("/users", json=user_data)
# Assert
assert response.status_code == 201
assert response.json()["name"] == "John"
DRY (Don't Repeat Yourself)
Избегание дублирования
# Плохо — дублирование
def test_1():
driver = webdriver.Chrome()
driver.get("https://example.com")
# Тест
driver.quit()
def test_2():
driver = webdriver.Chrome()
driver.get("https://example.com")
# Тест
driver.quit()
# Хорошо — использование fixture
@pytest.fixture
def driver():
d = webdriver.Chrome()
d.get("https://example.com")
yield d
d.quit()
def test_1(driver):
# Тест
pass
def test_2(driver):
# Тест
pass
Dependency Injection
Внедрение зависимостей
class UserService:
def __init__(self, database):
self.db = database
def get_user(self, user_id):
return self.db.find_user(user_id)
# Для тестирования подаем mock
class MockDB:
def find_user(self, user_id):
return {"id": 1, "name": "John"}
service = UserService(MockDB())
assert service.get_user(1)["name"] == "John"
Strategy Pattern
Легко менять поведение
class APITest:
def __init__(self, strategy):
self.strategy = strategy
def run(self):
return self.strategy.execute()
class GetStrategy:
def execute(self):
return requests.get("https://api.example.com/users")
class PostStrategy:
def execute(self):
return requests.post("https://api.example.com/users", json={})
test = APITest(GetStrategy())
response = test.run()
Использование в практике
Page Object Model — для UI тестов
Factory — для создания тестовых данных
Builder — для сложных объектов
AAA — для структуры тестов
Dependency Injection — для mockирования
Strategy — для тестирования разных сценариев
Паттерны делают тесты более читаемыми, переиспользуемыми и легкими в поддержке.