Какие критерии правильного автотеста для веб-приложения?

«Какие критерии правильного автотеста для веб-приложения?» — вопрос из категории Веб-тестирование, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для меня хороший автотест — это не просто проходящая проверка, а надежный, понятный и легко поддерживаемый артефакт. Я руководствуюсь следующими принципами:

1. Изолированность и независимость: Каждый тест должен запускаться в предсказуемом состоянии. Я добиваюсь этого через @BeforeEach/@AfterEach хуки, которые подготавливают данные (например, создают тестового пользователя через API) и очищают за собой.

2. Детерминированность (стабильность): Тест должен всегда давать одинаковый результат. Я избегаю жестких Thread.sleep(), используя явные ожидания (WebDriverWait), и работаю с уникальными тестовыми данными.

3. Читаемость и простота: Название теста (userShouldSeeErrorMessageOnLoginWithInvalidPassword) и шаги внутри должны четко описывать сценарий. Я использую паттерн Page Object Model (POM), чтобы вынести логику взаимодействия с элементами страницы в отдельные классы.

4. Фокус на одной проверке: Один тест — одна бизнес-логика. Это упрощает определение причины падения.

5. Полезность отчетов: При падении тест должен давать максимально понятную ошибку. Я добавляю информативные сообщения в ассерты и логирую ключевые действия.

Пример плохого и хорошего теста:

Плохо (хрупкий и нечитаемый):

@Test
public void test1() {
    driver.findElement(By.id("user-name")).sendKeys("user");
    driver.findElement(By.id("password")).sendKeys("password");
    driver.findElement(By.id("login-button")).click();
    Thread.sleep(2000); // Хрупкая пауза
    Assert.assertTrue(driver.getCurrentUrl().contains("inventory")); // Неясное сообщение об ошибке
}

Хорошо (с POM и явными ожиданиями):

@Test
@DisplayName("Пользователь не может войти с некорректным паролем")
public void userCannotLoginWithInvalidPassword() {
    LoginPage loginPage = new LoginPage(driver);
    loginPage.open();
    loginPage.enterUsername("standard_user");
    loginPage.enterPassword("wrong_password");
    loginPage.clickLoginButton();
    String errorText = loginPage.getErrorMessageText();
    Assertions.assertEquals("Epic sadface: Username and password do not match any user in this service",
                            errorText,
                            "Текст ошибки при неверном логине/пароле не совпадает");
}