Что такое принцип DRY?

Ответ

DRY (Don't Repeat Yourself) — это принцип разработки, направленный на снижение дублирования логики в коде. Основная идея: каждая часть знания или логики должна иметь единственное, однозначное представление в системе.

Почему DRY критически важен в тестировании? Дублирование в тестах приводит к:

  1. Хрупкости: Изменение в одном месте (например, селектора элемента или шага логина) требует правок во множестве тестов.
  2. Усложнению поддержки: Большой объем повторяющегося кода сложнее читать и обновлять.
  3. Увеличению времени на написание тестов.

Как я применяю DRY в тестовом коде:

  • Вынос общих шагов в методы-хелперы или утилитные классы.

    // Вместо дублирования логина в каждом тесте:
    public class AuthHelper {
        public static void login(WebDriver driver, String user, String pass) {
            driver.findElement(By.id("user")).sendKeys(user);
            driver.findElement(By.id("pass")).sendKeys(pass);
            driver.findElement(By.id("login-btn")).click();
        }
    }
    // Использование в тесте:
    AuthHelper.login(driver, "standard_user", "secret_sauce");
  • Использование фикстур (в Pytest) или @BeforeMethod (в TestNG) для предварительной настройки тестового окружения.

    # pytest фикстура для драйвера
    import pytest
    from selenium import webdriver
    
    @pytest.fixture(scope="function")
    def browser():
        driver = webdriver.Chrome()
        driver.get(BASE_URL)
        yield driver
        driver.quit()
    
    # Тест использует фикстуру, не создавая драйвер сам
    def test_search(browser):
        browser.find_element(By.NAME, "q").send_keys("Selenium")
  • Применение Page Object Model, который сам по себе является реализацией DRY, так как локаторы и базовые действия с элементами страницы описаны в одном месте.

  • Параметризация тестов для запуска одного тестового метода с разными наборами данных.

    @Test
    @Parameters({"admin, admin123, true", "user, wrongpass, false"})
    public void testLoginParametrized(String username, String password, boolean expectedSuccess) {
        loginPage.login(username, password);
        Assert.assertEquals(loginPage.isLoginSuccessful(), expectedSuccess);
    }

Следование DRY делает тестовую кодобазу чище, стабильнее и значительно упрощает ее масштабирование.

Ответ 18+ 🔞

А, DRY, ну это же святое, ёпта! Принцип «Не Повторяйся» — это как заповедь для любого адекватного программиста, который не хочет в будущем сойти с ума от поддержки своего же кода. Особенно в тестах, где однообразие и шаблонность — это просто пиздец какой-то бич.

Представь: у тебя двадцать тестов на логин, и в каждом ты пишешь одно и то же — открыть браузер, вбить юзера, вбить пароль, кликнуть кнопку. А потом дизайнеры взяли и поменяли id у поля пароля с "pass" на "password". И что, ты теперь будешь как полупидор, ползать по всем двадцати файлам и править это дерьмо? Волнение ебать! Терпения ноль ебать на такое. Вот именно от этого и спасает DRY.

Как я это обычно делаю, чтобы не превратить тесты в манда с ушами:

  1. Хелперы — наши лучшие друзья. Всю повторяющуюся поеботу — логин, логаут, генерацию тестовых данных — выносим в отдельные классы или методы. Один раз написал, везде используешь.

    // Раньше было: копипаста в каждом втором тесте. Пиздопроебибна.
    // Теперь: один метод на все случаи жизни. Красота.
    public class AuthHelper {
        public static void login(WebDriver driver, String user, String pass) {
            driver.findElement(By.id("user")).sendKeys(user);
            driver.findElement(By.id("pass")).sendKeys(pass); // поменяли тут id - и всё, фикс в одном месте
            driver.findElement(By.id("login-btn")).click();
        }
    }
    // В тесте теперь элегантно и коротко:
    AuthHelper.login(driver, "standard_user", "secret_sauce");
  2. Фикстуры и @Before-методы — магия предварительной настройки. Зачем в каждом тесте руками создавать драйвер и открывать страницу? Да похуй! Пусть это делает фреймворк перед каждым тестом.

    # Фикстура в pytest — это просто песня. Настроил один раз — пользуешься везде.
    import pytest
    from selenium import webdriver
    
    @pytest.fixture(scope="function")
    def browser():
        driver = webdriver.Chrome()
        driver.get(BASE_URL) # Базовая урла тоже в одном месте
        yield driver # Отдаём готовый драйвер тесту
        driver.quit() # И после теста аккуратно закрываем
    
    # Сам тест теперь чистый, только бизнес-логика.
    def test_search(browser): # Фикстура 'browser' автоматом подсунулась сюда
        browser.find_element(By.NAME, "q").send_keys("Selenium")
  3. Page Object — это вообще основа основ. Это высшая форма DRY для UI-тестов. Все локаторы и простейшие действия с элементами (клик, ввод текста) живут в одном месте — в классе страницы. Изменился селектор? Хуй с горы! Меняешь в одном файле, а не в овердохуище тестов.

  4. Параметризация — чтобы не плодить однотипные методы. Нужно проверить логин для трёх разных пользователей? Не пиши три одинаковых теста! Напиши один, но скажи ему: «Чувак, вот тебе три набора данных, прогуляйся по ним».

    @Test
    @Parameters({"admin, admin123, true", "user, wrongpass, false", "guest, , false"})
    public void testLoginParametrized(String username, String password, boolean expectedSuccess) {
        loginPage.login(username, password);
        Assert.assertEquals(loginPage.isLoginSuccessful(), expectedSuccess);
    }

Если коротко: DRY в тестах — это не прихоть, а вопрос выживания. Без него твоя тестовая база быстро превратится в такое монструозное, хрупкое нечто, что любое изменение в приложении будет вызывать тихий ужас и желание всё удалить и написать заново. А с DRY — всё чисто, модульно и поддерживать одно удовольствие. Ну, почти.

Видео-ответы