← Назад к вопросам

Что такое DRY?

1.0 Junior🔥 161 комментариев
#Архитектура приложений

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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 — это инвестиция в будущее. Применение этого принципа делает код:

  • Более пригодным для поддержки
  • Менее подверженным ошибкам
  • Более читаемым
  • Более быстрым в разработке новых тестов

Да, первоначально может быть чуть более сложным для написания абстракций, но это окупается стократ при поддержке и изменении кода.