Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
DRY принцип в разработке и автотестировании
DRY расшифровывается как "Don't Repeat Yourself" (Не Повторяй Себя) — один из ключевых принципов в разработке и автоматизации тестирования. Суть очень простая: если вы пишете одинаковый код в двух или более местах, это плохо. Код нужно вынести в отдельную функцию или утилиту, чтобы использовать её повторно.
Почему DRY важен
Проблемы без DRY:
- Сложнее для поддержки — нужно изменить логику в 10 местах вместо одного
- Подвержен ошибкам — легко что-то забыть при редактировании
- Тяжелее для понимания — новичку непонятно, есть ли разница в этих копиях
- Больше багов — при изменении требований приходится обновлять везде
Пример в UI-Автотестировании (Python + Selenium)
Плохо — дублирование кода:
def test_login():
driver = webdriver.Chrome()
driver.get("http://localhost:8080")
driver.find_element(By.ID, "username").send_keys("user@test.com")
driver.find_element(By.ID, "password").send_keys("password123")
driver.find_element(By.ID, "login_btn").click()
assert "dashboard" in driver.current_url
driver.quit()
def test_logout():
driver = webdriver.Chrome()
driver.get("http://localhost:8080")
driver.find_element(By.ID, "username").send_keys("user@test.com")
driver.find_element(By.ID, "password").send_keys("password123")
driver.find_element(By.ID, "login_btn").click()
driver.find_element(By.ID, "logout_btn").click()
assert "login" in driver.current_url
driver.quit()
Инициализация браузера и логин повторяется в обоих тестах!
Хорошо — применяем DRY с pytest fixtures:
@pytest.fixture
def browser():
driver = webdriver.Chrome()
yield driver
driver.quit()
@pytest.fixture
def logged_in_user(browser):
browser.get("http://localhost:8080")
browser.find_element(By.ID, "username").send_keys("user@test.com")
browser.find_element(By.ID, "password").send_keys("password123")
browser.find_element(By.ID, "login_btn").click()
return browser
def test_login(logged_in_user):
assert "dashboard" in logged_in_user.current_url
def test_logout(logged_in_user):
logged_in_user.find_element(By.ID, "logout_btn").click()
assert "login" in logged_in_user.current_url
Теперь логин-логика в одном месте, её легко изменить, тесты читаются проще.
Другие примеры DRY в Автотестах
Локаторы — вынеси в отдельный файл (Page Object Pattern):
class LoginPageLocators:
USERNAME_INPUT = (By.ID, "username")
PASSWORD_INPUT = (By.ID, "password")
LOGIN_BUTTON = (By.ID, "login_btn")
def test_login(browser):
browser.find_element(*LoginPageLocators.USERNAME_INPUT).send_keys("user@test.com")
browser.find_element(*LoginPageLocators.PASSWORD_INPUT).send_keys("password123")
browser.find_element(*LoginPageLocators.LOGIN_BUTTON).click()
Вспомогательные функции:
def login(browser, email, password):
browser.find_element(By.ID, "username").send_keys(email)
browser.find_element(By.ID, "password").send_keys(password)
browser.find_element(By.ID, "login_btn").click()
def test_valid_login(browser):
login(browser, "user@test.com", "password123")
assert "dashboard" in browser.current_url
def test_invalid_login(browser):
login(browser, "user@test.com", "wrong_password")
assert "error" in browser.current_url
DRY в Backend-тестировании
def create_test_user(db_session, email="test@example.com", name="Test"):
user = User(name=name, email=email)
db_session.add(user)
db_session.commit()
return user
def test_user_creation(db_session):
user = create_test_user(db_session)
assert user.id is not None
def test_user_update(db_session):
user = create_test_user(db_session, "update@test.com")
user.name = "Updated"
db_session.commit()
assert user.name == "Updated"
def test_user_email_validation(db_session):
user = create_test_user(db_session, "invalid_email")
assert not validate_email(user.email)
Выводы
DRY — это инвестиция в будущее. Применение этого принципа делает код:
- Более пригодным для поддержки
- Менее подверженным ошибкам
- Более читаемым
- Более быстрым в разработке новых тестов
Да, первоначально может быть чуть более сложным для написания абстракций, но это окупается стократ при поддержке и изменении кода.